// Handles the player's squad.
// Worthless Bums 2012.


// Test function to debug timer.
function loopTimeStamps ()
{//echo("loopTimeStamps()");
	echo("getScriptTimer() =" SPC getScriptTimer());
	echo("$activeCharacter =" SPC $activeCharacter);
	$LoopTimeStampsEvent = schedule(25, 0, loopTimeStamps);
}

// Test function to stress test the player controls.
function startStressTest (%repeatTimer)//startStressTest(250);
{//echo("startStressTest()");
	$rwTimer = %repeatTimer;
	if ($rwTimer <= 0)
	{
		$rwTimer = 250;
	}
	rw();
}

// Test function to make the active character wander randomly.
function rw ()
{//echo("rw()");
	/*if (!isEventPending($LoopTimeStampsEvent))
	{
		loopTimeStamps();
	}*/
	
	/*if ($CapCounter >= 33)		// $CapCounter == 34 seems to crash!
	{
		cancelRw();
		return false;
	}*/
	
	// CRASH TESTING.
	/*$playerSquad[0].currentActionPoints = 1;
	$playerSquad[1].currentActionPoints = 1;
	$playerSquad[2].currentActionPoints = 1;
	$playerSquad[3].currentActionPoints = 1;
	//faceDown(1);
	switch (getRandom(0, 3))		// No different; $CapCount == 34 crashes!
	{
		case 0: faceUp(1);
		case 1: faceDown(1);
		case 2: faceLeft(1);
		case 3: faceRight(1);
	}
	$rwTimer = 100;	//	50 - 34, 100 - 46/47/49, 200 - 34, 400 - 34, 800 - 34... ???
	$rwEvent = schedule($rwTimer, 0, "rw");*/
	
	// MOVEMENT TESTING.
	$playerSquad[0].currentHealth = 99;
	$playerSquad[1].currentHealth = 99;
	$playerSquad[2].currentHealth = 99;
	$playerSquad[3].currentHealth = 99;
	$playerSquad[0].currentActionPoints = 1;
	$playerSquad[1].currentActionPoints = 1;
	$playerSquad[2].currentActionPoints = 1;
	$playerSquad[3].currentActionPoints = 1;
	cycleCharacter(0);
	//$playerSquad[$activecharacter].currentHealth = 999;
	%actionOption = getRandom(0, 2);
	//%actionOption = 1;
	switch (%actionOption)
	{
		case 0:
			switch (getRandom(0, 3))
			{
				case 0: faceUp(1);
				case 1: faceDown(1);
				case 2: faceLeft(1);
				case 3: faceRight(1);
			}
			
		case 1:
			moveCharacter($activeCharacter, getRandom(1, 4));
			
		case 2:
			fireWeaponInDirection(getRandom(1, 4));
	}
	//$rwTimer = 250;
	$rwEvent = schedule($rwTimer, 0, "rw");
	
	
	// Elevator/Level generation testing.
	/*switch ($YelizavetaAlexandrovnaShulyayeva)
	{
		case 0:
			testStairs();
			$YelizavetaAlexandrovnaShulyayeva = 1;
			
		case 1:
			// Nothing here yet!
			
		case 2:
			onwardButton();
			$YelizavetaAlexandrovnaShulyayeva = 0;
	}
	
	$rwTimer = 5000;
	$rwEvent = schedule($rwTimer, 0, "rw");*/
}
function cancelRw ()
{//echo("cancelRw()");
	if (isEventPending($rwEvent))
	{
		cancel($rwEvent);
	}
}

// Test function to fast cycle.
function fastCycleTest ()
{//echo("fastCycleTest()");
	cycleCharacter(0);
	$fctEvent = schedule(50, 0, "fastCycleTest");
}
function cancelFastCycleTest ()
{//echo("cancelFastCycleTest()");
	if (isEventPending($fctEvent))
	{
		cancel($fctEvent);
	}
}

// Test function to send active character to the stairs.
function gts ()
{//echo("gts()");
	$playerSquad[$activeCharacter].setPosition($stairsPositionX, $stairsPositionY);
}

// Deplete squad members' action points.
function squadDepleteActionPoints ()
{//echo("squadDepleteActionPoints()");
	$playerSquad[0].currentActionPoints = 0;
	$playerSquad[1].currentActionPoints = 0;
	$playerSquad[2].currentActionPoints = 0;
	$playerSquad[3].currentActionPoints = 0;
	return true;
}

// Refund squad members' action points.
function squadRefundActionPoints ()
{//echo("squadRefundActionPoints()");
	$playerSquad[0].currentActionPoints = $playerSquad[0].maxActionPoints;
	$playerSquad[1].currentActionPoints = $playerSquad[1].maxActionPoints;
	$playerSquad[2].currentActionPoints = $playerSquad[2].maxActionPoints;
	$playerSquad[3].currentActionPoints = $playerSquad[3].maxActionPoints;
	if ($leaderStatus == $paralyzeEffect)
	{
		$playerSquad[0].currentActionPoints = 0;
	}
	if ($scoutStatus == $paralyzeEffect)
	{
		$playerSquad[1].currentActionPoints = 0;
	}
	if ($grenadierStatus == $paralyzeEffect)
	{
		$playerSquad[2].currentActionPoints = 0;
	}
	if ($supportStatus == $paralyzeEffect)
	{
		$playerSquad[3].currentActionPoints = 0;
	}
	initializeReadout();
	updateSquadMemberFloatingActionPoints();
	return true;
}

// Manages current action points for the squad.
function setCurrentActionPoints (%characterIndex, %actionPoints)
{//echo("setCurrentActionPoints()");
	// Make sure there isn't already the same request in the queue.
	for (%i = 0; %i < $SquadCurrentActionPointQueue.getCount(); %i++)
	{
		%request = $SquadCurrentActionPointQueue.getObject(%i);
		if (%request.characterIndex == %characterIndex	&&
			%request.actionPoints == %actionPoints)
		{
			$SquadCurrentActionPointQueue.remove(%request);
		}
	}
	%changeRequest = new ScriptObject()
	{
		characterIndex = %characterIndex;
		actionPoints = %actionPoints;
	};
	$SquadCurrentActionPointQueue.add(%changeRequest);
	if (!$SquadCurrentActionPointsLock	&&
		$SquadCurrentActionPointQueue.getCount() > 0)
	{
		$SquadCurrentActionPointsLock = true;
		//echo("locked!");
		if (isObject($playerSquad[%characterIndex]))
		{
			%request = $SquadCurrentActionPointQueue.getObject(0);
			$playerSquad[%request.characterIndex].currentActionPoints = %request.actionPoints;
			switch (%request.actionPoints)
			{
				case 0:	$playerSquad[%request.characterIndex].currentActionPoints = 0;	// Setting this allows auto-switch which causes crashes!
				case 1:	$playerSquad[%request.characterIndex].currentActionPoints = 1;
				case 2:	$playerSquad[%request.characterIndex].currentActionPoints = 2;
				case 3:	$playerSquad[%request.characterIndex].currentActionPoints = 3;
				case 4:	$playerSquad[%request.characterIndex].currentActionPoints = 4;
				case 5:	$playerSquad[%request.characterIndex].currentActionPoints = 5;
				case 6:	$playerSquad[%request.characterIndex].currentActionPoints = 6;
				case 7:	$playerSquad[%request.characterIndex].currentActionPoints = 7;
				case 8:	$playerSquad[%request.characterIndex].currentActionPoints = 8;
				case 9:	$playerSquad[%request.characterIndex].currentActionPoints = 9;
			}
			$SquadCurrentActionPointQueue.remove(%request);
		}
		$SquadCurrentActionPointsLock = false;
	}
}

function setSquadAroundActiveCharacter ()
{//echo("setSquadAroundActiveCharacter()");echo("$activeCharacter =" SPC $activeCharacter);
	switch ($activeCharacter)
	{
		case 0:
		//echo("PLACING SURVIVOR 0!");
			if (isObject($playerSquad[1]))
			{//echo("slot 1 exists!");
				$playerSquad[1].xIndex = $playerSquad[$activeCharacter].xIndex;
				$playerSquad[1].yIndex = $playerSquad[$activeCharacter].yIndex - 1;
				$playerSquad[1].setPosition(getTilePositionFromIndices($playerSquad[1].xIndex, $playerSquad[1].yIndex));
				handleLiftedTileMarker($playerSquad[1]);
			}
			if (isObject($playerSquad[2]))
			{//echo("slot 2 exists!");
				$playerSquad[2].xIndex = $playerSquad[$activeCharacter].xIndex - 1;
				$playerSquad[2].yIndex = $playerSquad[$activeCharacter].yIndex;
				$playerSquad[2].setPosition(getTilePositionFromIndices($playerSquad[2].xIndex, $playerSquad[2].yIndex));
				handleLiftedTileMarker($playerSquad[2]);
			}
			if (isObject($playerSquad[3]))
			{//echo("slot 3 exists!");
				$playerSquad[3].xIndex = $playerSquad[$activeCharacter].xIndex - 1;
				$playerSquad[3].yIndex = $playerSquad[$activeCharacter].yIndex - 1;
				$playerSquad[3].setPosition(getTilePositionFromIndices($playerSquad[3].xIndex, $playerSquad[3].yIndex));
				handleLiftedTileMarker($playerSquad[3]);
			}
			
		case 1:
		//echo("PLACING SURVIVOR 1!");
			if (isObject($playerSquad[0]))
			{//echo("slot 0 exists!");
				$playerSquad[0].xIndex = $playerSquad[$activeCharacter].xIndex;
				$playerSquad[0].yIndex = $playerSquad[$activeCharacter].yIndex + 1;
				$playerSquad[0].setPosition(getTilePositionFromIndices($playerSquad[0].xIndex, $playerSquad[0].yIndex));
				handleLiftedTileMarker($playerSquad[0]);
			}
			if (isObject($playerSquad[2]))
			{//echo("slot 2 exists!");
				$playerSquad[2].xIndex = $playerSquad[$activeCharacter].xIndex - 1;
				$playerSquad[2].yIndex = $playerSquad[$activeCharacter].yIndex + 1;
				$playerSquad[2].setPosition(getTilePositionFromIndices($playerSquad[2].xIndex, $playerSquad[2].yIndex));
				handleLiftedTileMarker($playerSquad[2]);
			}
			if (isObject($playerSquad[3]))
			{//echo("slot 3 exists!");
				$playerSquad[3].xIndex = $playerSquad[$activeCharacter].xIndex - 1;
				$playerSquad[3].yIndex = $playerSquad[$activeCharacter].yIndex;
				$playerSquad[3].setPosition(getTilePositionFromIndices($playerSquad[3].xIndex, $playerSquad[3].yIndex));
				handleLiftedTileMarker($playerSquad[3]);
			}
			
		case 2:
		//echo("PLACING SURVIVOR 2!");
			if (isObject($playerSquad[0]))
			{//echo("slot 0 exists!");
				$playerSquad[1].xIndex = $playerSquad[$activeCharacter].xIndex + 1;
				$playerSquad[1].yIndex = $playerSquad[$activeCharacter].yIndex;
				$playerSquad[1].setPosition(getTilePositionFromIndices($playerSquad[0].xIndex, $playerSquad[0].yIndex));
				handleLiftedTileMarker($playerSquad[1]);
			}
			if (isObject($playerSquad[1]))
			{//echo("slot 1 exists!");
				$playerSquad[2].xIndex = $playerSquad[$activeCharacter].xIndex + 1;
				$playerSquad[2].yIndex = $playerSquad[$activeCharacter].yIndex - 1;
				$playerSquad[2].setPosition(getTilePositionFromIndices($playerSquad[1].xIndex, $playerSquad[1].yIndex));
				handleLiftedTileMarker($playerSquad[2]);
			}
			if (isObject($playerSquad[3]))
			{//echo("slot 3 exists!");
				$playerSquad[1].xIndex = $playerSquad[$activeCharacter].xIndex;
				$playerSquad[1].yIndex = $playerSquad[$activeCharacter].yIndex - 1;
				$playerSquad[1].setPosition(getTilePositionFromIndices($playerSquad[3].xIndex, $playerSquad[3].yIndex));
				handleLiftedTileMarker($playerSquad[1]);
			}
			
		case 3:
		//echo("PLACING SURVIVOR 3!");
			if (isObject($playerSquad[0]))
			{//echo("slot 0 exists!");
				$playerSquad[0].xIndex = $playerSquad[$activeCharacter].xIndex + 1;
				$playerSquad[0].yIndex = $playerSquad[$activeCharacter].yIndex + 1;
				$playerSquad[0].setPosition(getTilePositionFromIndices($playerSquad[0].xIndex, $playerSquad[0].yIndex));
			//echo("pre handleLiftedTileMarker()");
				handleLiftedTileMarker($playerSquad[0]);
			//echo("post handleLiftedTileMarker()");
			}
			if (isObject($playerSquad[1]))
			{//echo("slot 1 exists!");
				$playerSquad[1].xIndex = $playerSquad[$activeCharacter].xIndex + 1;
				$playerSquad[1].yIndex = $playerSquad[$activeCharacter].yIndex;
				$playerSquad[1].setPosition(getTilePositionFromIndices($playerSquad[1].xIndex, $playerSquad[1].yIndex));
			//echo("pre handleLiftedTileMarker()");
				handleLiftedTileMarker($playerSquad[1]);
			//echo("post handleLiftedTileMarker()");
			}
			if (isObject($playerSquad[2]))
			{//echo("slot 2 exists!");
				$playerSquad[2].xIndex = $playerSquad[$activeCharacter].xIndex;
				$playerSquad[2].yIndex = $playerSquad[$activeCharacter].yIndex - 1;
				$playerSquad[2].setPosition(getTilePositionFromIndices($playerSquad[2].xIndex, $playerSquad[2].yIndex));
			//echo("pre handleLiftedTileMarker()");
				handleLiftedTileMarker($playerSquad[2]);
			//echo("post handleLiftedTileMarker()");
			}
	}
//echo("END 1");
//echo("END 2");
}

// Sends the live squad members to a free spot on the map.
// NOTE: If the map is too small/poorly formed this can be an infinite loop!
function moveSquadToFreeArea ()
{//echo("moveSquadToFreeArea()");
	if ($generateTutorialLevel)
	{
		if ($leaderPersist)
		{
			$playerSquad[0].xIndex = 3;
			$playerSquad[0].yIndex = 3;
			$playerSquad[0].setPosition(getTilePositionFromIndices($playerSquad[0].xIndex, $playerSquad[0].yIndex));
			handleLiftedTileMarker($playerSquad[0]);
		}
		if ($scoutPersist)
		{
			$playerSquad[1].xIndex = 3;
			$playerSquad[1].yIndex = 2;
			$playerSquad[1].setPosition(getTilePositionFromIndices($playerSquad[1].xIndex, $playerSquad[1].yIndex));
			handleLiftedTileMarker($playerSquad[1]);
		}
		if ($grenadierPersist)
		{
			$playerSquad[2].xIndex = 2;
			$playerSquad[2].yIndex = 3;
			$playerSquad[2].setPosition(getTilePositionFromIndices($playerSquad[2].xIndex, $playerSquad[2].yIndex));
			handleLiftedTileMarker($playerSquad[2]);
		}
		if ($supportPersist)
		{
			$playerSquad[3].xIndex = 2;
			$playerSquad[3].yIndex = 2;
			$playerSquad[3].setPosition(getTilePositionFromIndices($playerSquad[3].xIndex, $playerSquad[3].yIndex));
			handleLiftedTileMarker($playerSquad[3]);
		}
		setDefaultSquadFacing();
		$fogOfWar.showFogOfWar();
		return;
	}
	
	%freeAreaFound = false;
	do {
		%xIndex = getRandom(0, $mazeDimension - 1);
		%yIndex = getRandom(0, $mazeDimension - 1);
		//%distance = mAbs(VectorDist($stairsXIndex SPC $stairsYIndex, %xIndex SPC %yIndex));
		if (!isObject($mazeRoom[%xIndex, %yIndex])		&&
			//tileClearOfSquadMembers(%xIndex, %yIndex)	&&
			!isSpaceTile(%xIndex, %yIndex))//				&&
			//%distance >= $minimumElevatorDistance)
		{//echo("%distance =" SPC %distance);echo("random indices =" SPC %xIndex SPC %yIndex);echo("elevator indices =" SPC $stairsXIndex SPC $stairsYIndex);
			if (%xIndex + 1 < $mazeDimension - 1	&&
				%yIndex + 1 < $mazeDimension - 1)
			{
				if (!isObject($mazeRoom[%xIndex + 1, %yIndex])		&&
					!isObject($mazeRoom[%xIndex, %yIndex + 1])		&&
					!isObject($mazeRoom[%xIndex + 1, %yIndex + 1])	&&
					
					//tileClearOfSquadMembers(%xIndex + 1, %yIndex)	&&
					tileClearOfMonsters(%xIndex + 1, %yIndex)		&&
					
					//tileClearOfSquadMembers(%xIndex, %yIndex + 1)	&&
					tileClearOfMonsters(%xIndex, %yIndex + 1)		&&
					
					//tileClearOfSquadMembers(%xIndex + 1, %yIndex)	&&
					tileClearOfMonsters(%xIndex + 1, %yIndex)		&&
					
					!isSpaceTile(%xIndex, %yIndex))
				{
					%freeAreaFound = true;
				}
			}
		}
	} while (!%freeAreaFound)
	if ($leaderPersist)
	{
		$playerSquad[0].xIndex = %xIndex + 1;
		$playerSquad[0].yIndex = %yIndex + 1;
		$playerSquad[0].setPosition(getTilePositionFromIndices($playerSquad[0].xIndex, $playerSquad[0].yIndex));
		handleLiftedTileMarker($playerSquad[0]);
	}
	if ($scoutPersist)
	{
		$playerSquad[1].xIndex = %xIndex + 1;
		$playerSquad[1].yIndex = %yIndex;
		$playerSquad[1].setPosition(getTilePositionFromIndices($playerSquad[1].xIndex, $playerSquad[1].yIndex));
		handleLiftedTileMarker($playerSquad[1]);
	}
	if ($grenadierPersist)
	{
		$playerSquad[2].xIndex = %xIndex;
		$playerSquad[2].yIndex = %yIndex + 1;
		$playerSquad[2].setPosition(getTilePositionFromIndices($playerSquad[2].xIndex, $playerSquad[2].yIndex));
		handleLiftedTileMarker($playerSquad[2]);
	}
	if ($supportPersist)
	{
		$playerSquad[3].xIndex = %xIndex;
		$playerSquad[3].yIndex = %yIndex;
		$playerSquad[3].setPosition(getTilePositionFromIndices($playerSquad[3].xIndex, $playerSquad[3].yIndex));
		handleLiftedTileMarker($playerSquad[3]);
	}
	setDefaultSquadFacing();
	$fogOfWar.showFogOfWar();
}
// Returns true iff all squad members are dead.
function isSquadDead ()
{//echo("isSquadDead()");
	if ($leaderPersist)
	{
		return false;
	}
	if ($scoutPersist)
	{
		return false;
	}
	if ($grenadierPersist)
	{
		return false;
	}
	if ($supportPersist)
	{
		return false;
	}
	return true;
}

// Set squad facing to default directions.
function setDefaultSquadFacing ()
{//echo("setDefaultSquadFacing()");
	if ($leaderPersist)
	{
		setSquadMemberIndexFacing($eastDirection, $playerSquad[0], 0);
	}
	if ($scoutPersist)
	{
		setSquadMemberIndexFacing($northDirection, $playerSquad[1], 1);	// Really south.
	}
	if ($grenadierPersist)
	{
		setSquadMemberIndexFacing($southDirection, $playerSquad[2], 2);	// Really north.
	}
	if ($supportPersist)
	{
		setSquadMemberIndexFacing($westDirection, $playerSquad[3], 3);
	}
}

// Mount squad's weapon sprites to their avatar sprites.
function mountSquadWeapons ()
{//echo("mountSquadWeapons()");
	clearSquadWeapons();
	if ($leaderPersist)
	{//echo("leader persist!");
		mountWeaponToCharacter($playerSquad[0].weapon, 0);
	}
	if ($scoutPersist)
	{//echo("scout persist!");
		mountWeaponToCharacter($playerSquad[1].weapon, 1);
	}
	if ($grenadierPersist)
	{//echo("grenadier persist!");
		mountWeaponToCharacter($playerSquad[2].weapon, 2);
	}
	if ($supportPersist)
	{//echo("support persist!");
		mountWeaponToCharacter($playerSquad[3].weapon, 3);
	}
}

// Returns true iff all squads are close to the stairs.
// NOTE: Should this be in stairsHandler.cs?
function squadIsCloseToStairs ()
{//echo("squadIsCloseToStairs()");
	%leaderClose = false;
	%scoutClose = false;
	%grenadierClose = false;
	%supportClose = false;
	if (!$leaderPersist)
	{
		%leaderClose = true;
	}
	if (!$scoutPersist)
	{
		%scoutClose = true;
	}
	if (!$grenadierPersist)
	{
		%grenadierClose = true;
	}
	if (!$supportPersist)
	{
		%supportClose = true;
	}
	
	if (!isObject($elevatorZone))
	{
		return false;
	}
	
	// Loop through $elevatorZone indices and check against squad member indices.
	for (%i = 0; %i < $elevatorZone.getCount(); %i++)
	{
		// Grab the elevator zone tile.
		%elevatorZoneTile = $elevatorZone.getObject(%i);
		%xIndex = %elevatorZoneTile.xIndex;
		%yIndex = %elevatorZoneTile.yIndex;
		
		// Check Leader.
		if ($leaderPersist	&&
			!%leaderClose)
		{
			if ($playerSquad[0].xIndex == %xIndex	&&
				$playerSquad[0].yIndex == %yIndex)
			{
				%leaderClose = true;
			}
			else if ($playerSquad[0].xIndex == $stairsXIndex	&&
					 $playerSquad[0].yIndex == $stairsYIndex)
			{
				%leaderClose = true;
			}
		}
		// Check Scout.
		if ($scoutPersist	&&
			!%scoutClose)
		{
			if ($playerSquad[1].xIndex == %xIndex	&&
				$playerSquad[1].yIndex == %yIndex)
			{
				%scoutClose = true;
			}
			else if ($playerSquad[1].xIndex == $stairsXIndex	&&
					 $playerSquad[1].yIndex == $stairsYIndex)
			{
				%scoutClose = true;
			}
		}
		// Check Grenadier.
		if ($grenadierPersist	&&
			!%grenadierClose)
		{
			if ($playerSquad[2].xIndex == %xIndex	&&
				$playerSquad[2].yIndex == %yIndex)
			{
				%grenadierClose = true;
			}
			else if ($playerSquad[2].xIndex == $stairsXIndex	&&
					 $playerSquad[2].yIndex == $stairsYIndex)
			{
				%grenadierClose = true;
			}
		}
		// Check Support.
		if ($supportPersist	&&
			!%supportClose)
		{
			if ($playerSquad[3].xIndex == %xIndex	&&
				$playerSquad[3].yIndex == %yIndex)
			{
				%supportClose = true;
			}
			else if ($playerSquad[3].xIndex == $stairsXIndex	&&
					 $playerSquad[3].yIndex == $stairsYIndex)
			{
				%supportClose = true;
			}
		}
	}
	if (%leaderClose	&&
		%scoutClose		&&
		%grenadierClose	&&
		%supportClose)
	{
		return true;
	}
	return false;
}

// Wins the current game.
function gameWonMan ()
{//echo("gameWonMan()");
	hideHud();
	$playerSquad = null;
	checkSaveState();
	continueGameWon();
}
// Continue game won process.
function continueGameWon ()
{//echo("continueGameWon()");
	$guiInProgress = true;
	sceneWindow2D.endLevel();
	updateSaveStateDataDisplay();
	Canvas.showCursor();
	stopBGMOgg();
	playMainMenuMusic();
	$gameInProgress = false;
	initializeEndLevelScreenGui();
	endLevelScreenBackground.bitmap = "../../../Sprites/1/assets/images/UI/Backgrounds/GameVictory";
	endLevelScreenButton.command = "hideHud();Canvas.popDialog(endLevelScreenGui);initializeNgpScreen();Canvas.pushDialog(ngpScreenGui);";
	Canvas.schedule($endLevelScreenDelay, "pushDialog", endLevelScreenGui);
	Canvas.schedule($endLevelScreenDelay, "showCursor");
}

// Clean up New Game Plus.
function cleanUpNewGamePlus ()
{//echo("cleanUpNewGamePlus()");
	Canvas.popDialog(ngpScreenGui);
	updateMainMenuSaveStateDeckLevelText();	// To update NG+ status on the deck/level preview.
	pushMainMenu();	
}

// Initializes the New Game Plus screen GUI.
function initializeNgpScreen ()
{//echo("initializeNgpScreen()");
	// Automatic Scroller needs to reset!
	// NOTE: Is there no better way to do this?!?
	exec("~/gui/ngpScreen.gui");
	
	ngpScreenDescription.setText("");
	ngpScreenStats.setText("");
	%scoreText = "\n\n\n\n\n\n\nWell done, marines. You've cleared\nthis ship of the invaders. But\nthe fleet is still in danger!\n\nPrepare to board the nearest\nvessel!\n\nYour score so far... " @ calculateCurrentScore();
	if ($gameIsDemo)
	{
		%scoreText = "\n\n\n\n\n\n\nYou've beaten the Steam Marines demo!\nVisit www.SteamMarines.com for the full version!" @ %scoreText;
	}
	ngpTextToScroll.setText(%scoreText @ "\n\n\n\n\n\n\nCredits\n\nCode & Game Design:\n\tYJ \"Worthless Bums\" Seow\n\nArt:\nJay Bramhall (Animations & Tilesets)\nAndre Mari Coppola (Splash Screens)\nMirko Koponen (Animations & Tilesets)\n\nMusic:\nLevan Iordanishvili\n\nSound:\nTapio Liukkonen\n\n\nSpecial thanks to:\nRobert Shenton for the Steam Marines logo!\nAlwaysGeeky for the Vox painting.\n\n\nPowered by Torque MIT v3.0\n\n\n\n\n\n\"If anything is bad, it's my fault.\nLike the UI.\"\n    - yjs\n\n\n\n\n\n\n\n\n\nThanks for playing!");
	// @Dwarfcorp "Completely Fair Games, Ltd."
}

// Ends the current tutorial.
function tutorialOverMan ()
{//echo("tutorialOverMan()");
	Canvas.popDialog(endLevelScreenGui);
	$NewGameStart = 0;
	$deathScreenPushed = false;
	$playerSquad = null;
	checkSaveState();
	continueGameOver();
}

// Ends the current game.
function gameOverMan ()
{//echo("gameOverMan()");
	Canvas.popDialog(endLevelScreenGui);
	$NewGameStart = 0;
	$deathScreenPushed = false;
	$playerSquad = null;
	clearSaveFile();
	checkSaveState();
	if (!isEventPending($showDeathScreenEvent))
	{
		$showDeathScreenEvent = schedule(100, 0, "showSquadDeathScreen");
	}
	continueGameOver();
}

// Continue game over process.
function continueGameOver ()
{//echo("continueGameOver()");
	sceneWindow2D.endLevel();
	updateSaveStateDataDisplay();
	Canvas.showCursor();
	stopBGMOgg();
	playMainMenuMusic();
	$gameInProgress = false;
}

// Makes sure squad member indices are correct!
function enforceSquadIndices ()
{//echo("enforceSquadIndices()");
	if ($leaderPersist)
	{
		if (isLargeUnit($playerSquad[0]))
		{
			%position = getTilePositionFromIndices($playerSquad[0].xIndex, $playerSquad[0].yIndex);
			$playerSquad[0].position = getWord(%position, 0) SPC (getWord(%position, 1) + $LargeUnitVerticalShift);
		}
		else
		{
			$playerSquad[0].position = getTilePositionFromIndices($playerSquad[0].xIndex, $playerSquad[0].yIndex);
		}
	}
	if ($scoutPersist)
	{
		if (isLargeUnit($playerSquad[1]))
		{
			%position = getTilePositionFromIndices($playerSquad[1].xIndex, $playerSquad[1].yIndex);
			$playerSquad[1].position = getWord(%position, 0) SPC (getWord(%position, 1) + $LargeUnitVerticalShift);
		}
		else
		{
			$playerSquad[1].position = getTilePositionFromIndices($playerSquad[1].xIndex, $playerSquad[1].yIndex);
		}
	}
	if ($grenadierPersist)
	{
		if (isLargeUnit($playerSquad[2]))
		{
			%position = getTilePositionFromIndices($playerSquad[2].xIndex, $playerSquad[2].yIndex);
			$playerSquad[2].position = getWord(%position, 0) SPC (getWord(%position, 1) + $LargeUnitVerticalShift);
		}
		else
		{
			$playerSquad[2].position = getTilePositionFromIndices($playerSquad[2].xIndex, $playerSquad[2].yIndex);
		}
	}
	if ($supportPersist)
	{
		if (isLargeUnit($playerSquad[3]))
		{
			%position = getTilePositionFromIndices($playerSquad[3].xIndex, $playerSquad[3].yIndex);
			$playerSquad[3].position = getWord(%position, 0) SPC (getWord(%position, 1) + $LargeUnitVerticalShift);
		}
		else
		{
			$playerSquad[3].position = getTilePositionFromIndices($playerSquad[3].xIndex, $playerSquad[3].yIndex);
		}
	}
}
// Makes sure squad member positions are correct!
function enforceSquadPosition ()
{//echo("enforceSquadPosition()");
	if ($leaderPersist)
	{
		if (isLargeUnit($playerSquad[0]))
		{
			%indices = getTallIndicesFromTilePosition(getWord($playerSquad[0].getPosition(), 0), getWord($playerSquad[0].getPosition(), 1));
			$playerSquad[0].xIndex = mRound(getWord(%indices, 0));
			$playerSquad[0].yIndex = mRound(getWord(%indices, 1));
		}
		else
		{
			%indices = getIndicesFromTilePosition(getWord($playerSquad[0].getPosition(), 0), getWord($playerSquad[0].getPosition(), 1));
			$playerSquad[0].xIndex = mRound(getWord(%indices, 0));
			$playerSquad[0].yIndex = mRound(getWord(%indices, 1));
		}
	}
	if ($scoutPersist)
	{
		if (isLargeUnit($playerSquad[1]))
		{
			%indices = getTallIndicesFromTilePosition(getWord($playerSquad[1].getPosition(), 0), getWord($playerSquad[1].getPosition(), 1));
			$playerSquad[1].xIndex = mRound(getWord(%indices, 0));
			$playerSquad[1].yIndex = mRound(getWord(%indices, 1));
		}
		else
		{
			%indices = getIndicesFromTilePosition(getWord($playerSquad[1].getPosition(), 0), getWord($playerSquad[1].getPosition(), 1));
			$playerSquad[1].xIndex = mRound(getWord(%indices, 0));
			$playerSquad[1].yIndex = mRound(getWord(%indices, 1));
		}
	}
	if ($grenadierPersist)
	{
		if (isLargeUnit($playerSquad[2]))
		{
			%indices = getTallIndicesFromTilePosition(getWord($playerSquad[2].getPosition(), 0), getWord($playerSquad[2].getPosition(), 1));
			$playerSquad[2].xIndex = mRound(getWord(%indices, 0));
			$playerSquad[2].yIndex = mRound(getWord(%indices, 1));
		}
		else
		{
			%indices = getIndicesFromTilePosition(getWord($playerSquad[2].getPosition(), 0), getWord($playerSquad[2].getPosition(), 1));
			$playerSquad[2].xIndex = mRound(getWord(%indices, 0));
			$playerSquad[2].yIndex = mRound(getWord(%indices, 1));
		}
	}
	if ($supportPersist)
	{//echo("$playerSquad[3].xIndex, $playerSquad[3].yIndex =" SPC $playerSquad[3].xIndex @ ", " @ $playerSquad[3].yIndex);
		if (isLargeUnit($playerSquad[3])	&&
			isObject($mazeLiftedTiles[$playerSquad[3].xIndex, $playerSquad[3].yIndex]))
		{
			%indices = getTallIndicesFromTilePosition(getWord($playerSquad[3].getPosition(), 0), getWord($playerSquad[3].getPosition(), 1));
			$playerSquad[3].xIndex = mRound(getWord(%indices, 0));
			$playerSquad[3].yIndex = mRound(getWord(%indices, 1));
		}
		else
		{
			%indices = getIndicesFromTilePosition(getWord($playerSquad[3].getPosition(), 0), getWord($playerSquad[3].getPosition(), 1));
			$playerSquad[3].xIndex = mRound(getWord(%indices, 0));
			$playerSquad[3].yIndex = mRound(getWord(%indices, 1));
		}
	}
	enforceSquadIndices();
}
// Makes sure squad member persistence is correct!
function enforceSquadPersistence ()
{//echo("enforceSquadPersistence()");
	if (!isObject($playerSquad[0]))
	{
		$leaderPersist = false;
	}
	else
	{
		$leaderPersist = true;
	}
	if (!isObject($playerSquad[1]))
	{
		$scoutPersist = false;
	}
	else
	{
		$scoutPersist = true;
	}
	if (!isObject($playerSquad[2]))
	{
		$grenadierPersist = false;
	}
	else
	{
		$grenadierPersist = true;
	}
	if (!isObject($playerSquad[3]))
	{
		$supportPersist = false;
	}
	else
	{
		$supportPersist = true;
	}
}

// Handles a squad member's death.
function executeSquadMemberDeath (%characterIndex, %spawnCorpse, %threat)
{//echo("executeSquadMemberDeath()");
	if (%characterIndex != 0	&&
		%characterIndex != 1	&&
		%characterIndex != 2	&&
		%characterIndex != 3)
	{
		return;	// Don't kill invalid marines!
	}
	($playerSquad[%characterIndex].promotionAnimation).safeDelete();
	// Intercept death if the character is in a Hulk Suit!
	if ($playerSquad[%characterIndex].vehicle == 0	&&
		!isSpaceTile($playerSquad[%characterIndex].xIndex, $playerSquad[%characterIndex].yIndex))
	{
		removeUnitHulkSuit(%characterIndex);
		return;
	}
	
	// Delete HP/AP floating text.
	$playerSquad[%characterIndex].floatingHPText.safeDelete();
	$playerSquad[%characterIndex].floatingAPText.safeDelete();
	
	// Pause the game briefly to "sell" the death!
	//triggerSlowdownDeathEffect();
	
	// Trigger death message!
	showDeathMessage(%characterIndex);
	
	// Slow motion for squad member death.
	//setTimeScale($squadSlowMotionScale);
	updateEventText($squadColor @ $playerSquad[%characterIndex].name @ $damageColor @ " dies" @ $defaultColor @ "!");
	$GlobalStats.totalSquadMemberDeaths++;
	$squadMemberDiedThisLevel = true;
	updateMissionObjectives();
	playAudio("Audio:death", EffectsAudioVolume.value);
	if (%spawnCorpse)
	{
		spawnCorpse($playerSquad[%characterIndex].xIndex, $playerSquad[%characterIndex].yIndex, 0);
	}
	if (isObject($playerSquad[%characterIndex].liftedTileMarker))
	{
		($playerSquad[%characterIndex].liftedTileMarker).safeDelete();
	}
	$playerSquad[%characterIndex].safeDelete();
	switch (%characterIndex)
	{
		case 0:	$leaderPersist = false;
		case 1:	$scoutPersist = false;
		case 2:	$grenadierPersist = false;
		case 3:	$supportPersist = false;
	}
	
	schedule(150, 0, "continueExecuteSquadMemberDeath");
	
	$LastMarineName = $playerSquad[%characterIndex].name;
	$LastMarineClass = getCharacterClassName($playerSquad[%characterIndex].characterClass);
	$LastMarineRank = getRankName($playerSquad[%characterIndex].rank);
	$LastScore = calculateCurrentScore();
	$LastDeck = strreplace($overworldLocation, " Deck", "");
	$LastLevel = $dungeonLevel;
	$LastTurn = $GlobalStats.currentTurn;
	$LastThreat = %threat;
	$LastDeaths = $GlobalStats.totalSurvivorsRecruited + 4;		// Hack calculation!
}
// Continue squad member execution.
function continueExecuteSquadMemberDeath ()
{//echo("continueExecuteSquadMemberDeath()");
	$currentSquadSize--;
	enforceSquadPersistence();
	$fogOfWar.fullCoverFog();
	schedule(150, 0, "enforceSquadPersistence");	// SERIOUSLY DO THIS.
	setPortraits();
	updateSquadInfoGui();
	updateSquadInformationPanels();
	if ($leaderPersist		||
		$scoutPersist		||
		$grenadierPersist	||
		$supportPersist)
	{
		$autoSwitchSquadMemberEvent = schedule($autoSwitchSquadMemberDelay, 0, "autoSwitchSquadmember");
		createAutoSwitchAnimation($playerSquad[$activeCharacter].xIndex, $playerSquad[$activeCharacter].yIndex);
		$fogOfWar.schedule(500, "showFogOfWar");
	}
	else
	{
		if (isEventPending($SavePersistentStatsEvent))
		{
			cancel($SavePersistentStatsEvent);
		}
		$SavePersistentStatsEvent = schedule(50, 0, "savePersistentStats");
		pushEndLevelScreenGuiAsDeathScreen();
	}
	releaseCharacterActionLock();
}

function cancelAutoSwitchEvents ()
{//echo("cancelAutoSwitchEvents()");
	if (isEventPending($autoSwitchSquadMemberEvent))
	{
		cancel($autoSwitchSquadMemberEvent);
		if (isObject($AutoSwitchAnimation))
		{
			$AutoSwitchAnimation.safeDelete();
		}
	}
	if (isEventPending($SwitchSquadMemberEvent))
	{
		cancel($SwitchSquadMemberEvent);
		if (isObject($AutoSwitchAnimation))
		{
			$AutoSwitchAnimation.safeDelete();
		}
	}
}

// Updates squad character portraits in explore gui.
function updatePortraits ()
{//echo("setPortraits()");
//return;
	if ($leaderPersist)
	{
		switch ($playerSquad[0].characterClass)
		{
			case 0:	LeaderSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/LeaderPortrait");
			case 1:	LeaderSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/ScoutPortrait");
			case 2:	LeaderSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/GrenadierPortrait");
			case 3:	LeaderSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/SupportPortrait");
			case 4:	LeaderSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/EngineerPortrait");
		}
	}
	if ($scoutPersist)
	{
		switch ($playerSquad[1].characterClass)
		{
			case 0:	ScoutSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/LeaderPortrait");
			case 1:	ScoutSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/ScoutPortrait");
			case 2:	ScoutSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/GrenadierPortrait");
			case 3:	ScoutSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/SupportPortrait");
			case 4:	ScoutSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/EngineerPortrait");
		}
	}
	if ($grenadierPersist)
	{
		switch ($playerSquad[2].characterClass)
		{
			case 0:	GrenadierSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/LeaderPortrait");
			case 1:	GrenadierSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/ScoutPortrait");
			case 2:	GrenadierSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/GrenadierPortrait");
			case 3:	GrenadierSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/SupportPortrait");
			case 4:	GrenadierSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/EngineerPortrait");
		}
	}
	if ($supportPersist)
	{
		switch ($playerSquad[3].characterClass)
		{
			case 0:	SupportSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/LeaderPortrait");
			case 1:	SupportSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/ScoutPortrait");
			case 2:	SupportSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/GrenadierPortrait");
			case 3:	SupportSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/SupportPortrait");
			case 4:	SupportSidePortrait.setBitmap("../../../Sprites/1/assets/images/UI/Explore/EngineerPortrait");
		}
	}
}

// Handles squad character portraits.
function setPortraits ()
{//echo("setPortraits()");
	updatePortraits();
}

function getCharacterIndex (%squadMember)
{
	for (%i = 0; %i < 4; %i++)
	{
		if (isObject($playerSquad[%i])	&&
			%squadMember == $playerSquad[%i])
		{
			return %i;
		}
	}
}

// Switches to the specified squad member if he/she exists.
function selectSquadMember (%squadMember)
{//echo("selectSquadMember()");
	// Purge unused memory!
	purgeResources();
	
	clearTargetIndicators(false);
	if (isEventPending($autoSwitchSquadMemberEvent))
	{
		cancel($autoSwitchSquadMemberEvent);
	}
	switch (%squadMember)
	{
		case 0:
			if (!$leaderPersist)
			{
				return false;
			}
			
		case 1:
			if (!$scoutPersist)
			{
				return false;
			}
			
		case 2:
			if (!$grenadierPersist)
			{
				return false;
			}
			
		case 3:
			if (!$supportPersist)
			{
				return false;
			}
	}
	$activeCharacter = %squadMember;
	handleActiveCharacterIndicator();
	if ($sceneWindowMountParent != $playerSquad[$activeCharacter])
	{
		sceneWindow2D.mount($playerSquad[$activeCharacter], $sceneWindow2DxOffset SPC $sceneWindow2DyOffset, $cameraMountForce, false);		// Parameter list is: object to mount to, offset, force, do not send to mount!
		$sceneWindowMountParent = $playerSquad[$activeCharacter];
	}
	updateEventText($friendlyActionColor @ "Switching control to" SPC $squadColor @ $playerSquad[$activeCharacter].name @ $defaultColor @ ".");
	playAudio("Audio:switchSquadMember", EffectsAudioVolume.value);
	updateActiveCharacterTutorial();
	updateTalentBarIcons();
	autoTargetEnemyUnit($autoTargetDelay);
	initializeReadout();
	return true;
}
function switchToNextSquadMember ()
{//echo("switchToNextSquadMember()");
	if ($generateTutorialLevel)
	{
		if ($tutorialSection == 1)
		{
			tutorialMessage2();
		}
	}
	if (isEventPending($autoSwitchSquadMemberEvent))
	{
		cancel($autoSwitchSquadMemberEvent);
	}
	unlockFireControls();
	%indicatorBitmap = "../../../Sprites/1/assets/images/Active Character Indicator";
	switch ($activeCharacter)
	{
		case 0:	// Leader.
				// Switch to Scout.
				if ($scoutPersist)
				{
					$activeCharacter = 1;
				}
				else if ($grenadierPersist)
				{
					$activeCharacter = 2;
				}
				else if ($supportPersist)
				{
					$activeCharacter = 3;
				}
				
		case 1: // Scout
				// Switch to Grenadier.
				if ($grenadierPersist)
				{
					$activeCharacter = 2;
				}
				else if ($supportPersist)
				{
					$activeCharacter = 3;
				}
				else if ($leaderPersist)
				{
					$activeCharacter = 0;
				}
				
		case 2: // Grenadier
				// Switch to Support.
				if ($supportPersist)
				{
					$activeCharacter = 3;
				}
				else if ($leaderPersist)
				{
					$activeCharacter = 0;
				}
				else if ($scoutPersist)
				{
					$activeCharacter = 1;
				}
				
		case 3: // Support
				// Switch to Leader.
				if ($leaderPersist)
				{
					$activeCharacter = 0;
				}
				else if ($scoutPersist)
				{
					$activeCharacter = 1;
				}
				else if ($grenadierPersist)
				{
					$activeCharacter = 2;
				}
	}
	handleActiveCharacterIndicator();
	if ($sceneWindowMountParent != $playerSquad[$activeCharacter])
	{
		sceneWindow2D.dismount();
		sceneWindow2D.mount($playerSquad[$activeCharacter], $sceneWindow2DxOffset SPC $sceneWindow2DyOffset, $cameraMountForce, false);		// Parameter list is: object to mount to, offset, force, do not send to mount!
		$sceneWindowMountParent = $playerSquad[$activeCharacter];
	}
	updateEventText($friendlyActionColor @ "Switching control to" SPC $squadColor @ $playerSquad[$activeCharacter].name @ $defaultColor @ ".");
	playAudio("Audio:switchSquadMember", EffectsAudioVolume.value);
	updateActiveCharacterTutorial();
	updateTalentBarIcons();
	autoTargetEnemyUnit($autoTargetDelay);
	initializeReadout();
}
function switchToPreviousSquadMember ()
{//echo("switchToPreviousSquadMember()");
	if ($generateTutorialLevel)
	{
		if ($tutorialSection == 1)
		{
			tutorialMessage2();
		}
	}
	if (isEventPending($autoSwitchSquadMemberEvent))
	{
		cancel($autoSwitchSquadMemberEvent);
	}
	unlockFireControls();
	%indicatorBitmap = "../../../Sprites/1/assets/images/Active Character Indicator";
	switch ($activeCharacter)
	{
		case 0:	// Leader.
				// Switch to Support.
				if ($supportPersist)
				{
					$activeCharacter = 3;
				}
				else if ($grenadierPersist)
				{
					$activeCharacter = 2;
				}
				else if ($scoutPersist)
				{
					$activeCharacter = 1;
				}
				
		case 1: // Scout
				// Switch to Leader.
				if ($leaderPersist)
				{
					$activeCharacter = 0;
				}
				else if ($supportPersist)
				{
					$activeCharacter = 3;
				}
				else if ($grenadierPersist)
				{
					$activeCharacter = 2;
				}
				
		case 2: // Grenadier
				// Switch to Scout.
				if ($scoutPersist)
				{
					$activeCharacter = 1;
				}
				else if ($leaderPersist)
				{
					$activeCharacter = 0;
				}
				else if ($supportPersist)
				{
					$activeCharacter = 3;
				}
				
		case 3: // Support
				// Switch to Grenadier.
				if ($grenadierPersist)
				{
					$activeCharacter = 2;
				}
				else if ($scoutPersist)
				{
					$activeCharacter = 1;
				}
				else if ($leaderPersist)
				{
					$activeCharacter = 0;
				}
	}
	handleActiveCharacterIndicator();
	if ($sceneWindowMountParent != $playerSquad[$activeCharacter])
	{
		sceneWindow2D.dismount();
		sceneWindow2D.mount($playerSquad[$activeCharacter], $sceneWindow2DxOffset SPC $sceneWindow2DyOffset, $cameraMountForce, false);		// Parameter list is: object to mount to, offset, force, do not send to mount!
		$sceneWindowMountParent = $playerSquad[$activeCharacter];
	}
	updateEventText($friendlyActionColor @ "Switching control to" SPC $squadColor @ $playerSquad[$activeCharacter].name @ $defaultColor @ ".");
	playAudio("Audio:switchSquadMember", EffectsAudioVolume.value);
	updateActiveCharacterTutorial();
	updateTalentBarIcons();
	autoTargetEnemyUnit($autoTargetDelay);
	initializeReadout();
}
function createNewSquad (%scenegraph)
{//echo("createNewSquad()");
	// Check the current save state prior to creating the members of the new squad!
	checkSaveState();
	// A squad is limited to a maximum of four (4) characters.
	$maxSquadSize = 4;
	$currentSquadSize = 0;
	$playerSquad[$maxSquadSize] = 0;
	
	// New squads are ONLY created at the start of the game!
	// NOTE: We should allow the player to name/choose icons for the members of the squad, but for now just automate everything on a new game.
	// Set active character flag to non-value to test if anyone in the squad is still alive.
	$activeCharacter = -1;
	// Check if loading from a save state.
	if ($loadFromSave)
	{//echo("loading from save!");
		if ($leaderPersist)
		{//echo("leader persists!");
			// Create the Squad Leader.
			$leaderPersist = true;
			%gender = getRandom(0, 1);
			%imageMap = "Leader_64x64ImageMap";
			%x = -4000;
			%y = -4000;
			%xIndex = -4000;
			%yIndex = -4000;
			%mountCamera = true;
			// Spawn the Squad Leader at the specified position.
			$playerSquad[0] = spawnCharacterAtLocation(%scenegraph, 0, %gender, $leaderWeapon, $leaderArmor, %imageMap, %x, %y, %xIndex, %yIndex, %mountCamera, $leaderPerks);
			if ($activeCharacter == -1)
			{
				$activeCharacter = 0;
			}
			// Increment the squad size counter.
			$currentSquadSize++;			// Beware persistence!
		}
		
		if ($scoutPersist)
		{//echo("scout persists!");
			// Create the Scout.
			$scoutPersist = true;
			%gender = getRandom(0, 1);
			%imageMap = "Scout_64x64ImageMap";
			%x = -4000;
			%y = -4000;
			%xIndex = -4000;
			%yIndex = -4000;
			%mountCamera = false;
			// Spawn the Scout at the specified position.
			$playerSquad[1] = spawnCharacterAtLocation(%scenegraph, 1, %gender, $scoutWeapon, $scoutArmor, %imageMap, %x, %y, %xIndex, %yIndex, %mountCamera, $scoutPerks);
			if ($activeCharacter == -1)
			{
				$activeCharacter = 1;
			}
			// Increment the squad size counter.
			$currentSquadSize++;			// Beware persistence!
		}
		
		if ($grenadierPersist)
		{//echo("grenadier persists!");
			// Create the Grenadier.
			$grenadierPersist = true;
			%gender = getRandom(0, 1);
			%imageMap = "Grenadier_64x64ImageMap";
			%x = -4000;
			%y = -4000;
			%xIndex = -4000;
			%yIndex = -4000;
			%mountCamera = false;
			// Spawn the Grenadier at the specified position.
			$playerSquad[2] = spawnCharacterAtLocation(%scenegraph, 2, %gender, $grenadierWeapon, $grenadierArmor, %imageMap, %x, %y, %xIndex, %yIndex, %mountCamera, $grenadierPerks);
			if ($activeCharacter == -1)
			{
				$activeCharacter = 2;
			}
			// Increment the squad size counter.
			$currentSquadSize++;			// Beware persistence!
		}
		
		if ($supportPersist)
		{//echo("support persists!");
			// Create the Support.
			$supportPersist = true;
			%gender = getRandom(0, 1);
			%imageMap = "Support_64x64ImageMap";
			%x = -4000;
			%y = -4000;
			%xIndex = -4000;
			%yIndex = -4000;
			%mountCamera = false;
			// Spawn the Grenadier at the specified position.
			$playerSquad[3] = spawnCharacterAtLocation(%scenegraph, 3, %gender, $supportWeapon, $supportArmor, %imageMap, %x, %y, %xIndex, %yIndex, %mountCamera, $supportPerks);
			if ($activeCharacter == -1)
			{
				$activeCharacter = 3;
			}
			// Increment the squad size counter.
			$currentSquadSize++;			// Beware persistence!
		}
	}
	else
	{//echo("LOADING NEW SQUAD!");
		// Create the Squad Leader.
		$leaderPersist = true;
		%imageMap = "Leader_64x64ImageMap";		// Gets overwriten anyway!
		%x = -4000;
		%y = -4000;
		%xIndex = -4000;
		%yIndex = -4000;
		%mountCamera = true;
		
		// Grab character gender index.
		%gender = 0;
		switch$ ($leaderStartGender)
		{
			case "Male":	%gender = 1;
			case "Female":	%gender = 0;
		}
		// Grab character class index.
		%characterClass = 0;
		switch$ ($leaderStartClass)
		{
			case "Leader":		%characterClass = 0;
			case "Scout":		%characterClass = 1;
			case "Grenadier":	%characterClass = 2;
			case "Support":		%characterClass = 3;
			case "Engineer":	%characterClass = 4;
		}
		
		// Create a random weapon.
		%weaponCode = createRandomWeapon(%characterClass, $dungeonLevel);
		// Create a random armor.
		%armorCode = createRandomArmor(%characterClass, $dungeonLevel);
		// Spawn the Leader slot character with the necessary data.
		$playerSquad[0] = spawnCharacterAtLocation(%scenegraph, %characterClass, %gender, %weaponCode, %armorCode, %imageMap, %x, %y, %xIndex, %yIndex, %mountCamera, $leaderPerks);
		if ($activeCharacter == -1)
		{
			$activeCharacter = 0;
		}
		
		// Assign name.
		$playerSquad[0].name = $leaderStartName;
		
		// Adjust action points based on armor modifier.
		$playerSquad[0].maxActionPoints += ($playerSquad[0].armor).speed;
		$playerSquad[0].currentActionPoints = $playerSquad[0].maxActionPoints;
		// Increment the squad size counter.
		$currentSquadSize++;			// Beware persistence!
		
		
		// Create the Scout.
		$scoutPersist = true;
		%imageMap = "Scout_64x64ImageMap";
		%x = -4000;
		%y = -4000;
		%xIndex = -4000;
		%yIndex = -4000;
		%mountCamera = false;
		
		// Grab character gender index.
		%gender = 0;
		switch$ ($scoutStartGender)
		{
			case "Male":	%gender = 1;
			case "Female":	%gender = 0;
		}
		// Grab character class index.
		%characterClass = 0;
		switch$ ($scoutStartClass)
		{
			case "Leader":		%characterClass = 0;
			case "Scout":		%characterClass = 1;
			case "Grenadier":	%characterClass = 2;
			case "Support":		%characterClass = 3;
			case "Engineer":	%characterClass = 4;
		}
		
		// Create a random Scout weapon.
		%weaponCode = createRandomWeapon(%characterClass, $dungeonLevel);
		// Create a random Scout armor.
		%armorCode = createRandomArmor(%characterClass, $dungeonLevel);
		// Spawn the Scout at the specified position.
		$playerSquad[1] = spawnCharacterAtLocation(%scenegraph, %characterClass, %gender, %weaponCode, %armorCode, %imageMap, %x, %y, %xIndex, %yIndex, %mountCamera, $scoutPerks);
		if ($activeCharacter == -1)
		{
			$activeCharacter = 1;
		}
		
		// Assign name.
		$playerSquad[1].name = $scoutStartName;
		
		// Adjust action points based on armor modifier.
		$playerSquad[1].maxActionPoints += ($playerSquad[1].armor).speed;
		$playerSquad[1].currentActionPoints = $playerSquad[1].maxActionPoints;
		// Increment the squad size counter.
		$currentSquadSize++;			// Beware persistence!
		
		// Create the Grenadier.
		$grenadierPersist = true;
		%gender = getRandom(0, 1);
		%imageMap = "Grenadier_64x64ImageMap";
		%x = -4000;
		%y = -4000;
		%xIndex = -4000;
		%yIndex = -4000;
		%mountCamera = false;
		
		// Grab character gender index.
		%gender = 0;
		switch$ ($grenadierStartGender)
		{
			case "Male":	%gender = 1;
			case "Female":	%gender = 0;
		}
		// Grab character class index.
		%characterClass = 0;
		switch$ ($grenadierStartClass)
		{
			case "Leader":		%characterClass = 0;
			case "Scout":		%characterClass = 1;
			case "Grenadier":	%characterClass = 2;
			case "Support":		%characterClass = 3;
			case "Engineer":	%characterClass = 4;
		}
		
		// Create a random Grenadier weapon.
		%weaponCode = createRandomWeapon(%characterClass, $dungeonLevel);
		// Create a random Grenadier armor.
		%armorCode = createRandomArmor(%characterClass, $dungeonLevel);
		// Spawn the Grenadier at the specified position.
		$playerSquad[2] = spawnCharacterAtLocation(%scenegraph, %characterClass, %gender, %weaponCode, %armorCode, %imageMap, %x, %y, %xIndex, %yIndex, %mountCamera, $grenadierPerks);
		if ($activeCharacter == -1)
		{
			$activeCharacter = 2;
		}
		
		// Assign name.
		$playerSquad[2].name = $grenadierStartName;
		
		// Adjust action points based on armor modifier.
		$playerSquad[2].maxActionPoints += ($playerSquad[2].armor).speed;
		$playerSquad[2].currentActionPoints = $playerSquad[2].maxActionPoints;
		// Increment the squad size counter.
		$currentSquadSize++;			// Beware persistence!
		
		
		// Create the Support.
		$supportPersist = true;
		%gender = getRandom(0, 1);
		%imageMap = "Support_64x64ImageMap";
		%x = -4000;
		%y = -4000;
		%xIndex = -4000;
		%yIndex = -4000;
		%mountCamera = false;
		
		// Grab character gender index.
		%gender = 0;
		switch$ ($supportStartGender)
		{
			case "Male":	%gender = 1;
			case "Female":	%gender = 0;
		}
		// Grab character class index.
		%characterClass = 0;
		switch$ ($supportStartClass)
		{
			case "Leader":		%characterClass = 0;
			case "Scout":		%characterClass = 1;
			case "Grenadier":	%characterClass = 2;
			case "Support":		%characterClass = 3;
			case "Engineer":	%characterClass = 4;
		}
		
		// Create a random Support weapon.
		%weaponCode = createRandomWeapon(%characterClass, $dungeonLevel);
		// Create a random Support armor.
		%armorCode = createRandomArmor(%characterClass, $dungeonLevel);
		// Spawn the Support at the specified position.
		$playerSquad[3] = spawnCharacterAtLocation(%scenegraph, %characterClass, %gender, %weaponCode, %armorCode, %imageMap, %x, %y, %xIndex, %yIndex, %mountCamera, $supportPerks);
		if ($activeCharacter == -1)
		{
			$activeCharacter = 3;
		}
		
		// Assign name.
		$playerSquad[3].name = $supportStartName;
		
		// Adjust action points based on armor modifier.
		$playerSquad[3].maxActionPoints += ($playerSquad[3].armor).speed;
		$playerSquad[3].currentActionPoints = $playerSquad[3].maxActionPoints;
		// Increment the squad size counter.
		$currentSquadSize++;			// Beware persistence!
	}
	
	// Add stat and skill points!
	$playerSquad[0].statPoints  = 0;
	$playerSquad[0].skillPoints = 0;
	$playerSquad[1].statPoints  = 0;
	$playerSquad[1].skillPoints = 0;
	$playerSquad[2].statPoints  = 0;
	$playerSquad[2].skillPoints = 0;
	$playerSquad[3].statPoints  = 0;
	$playerSquad[3].skillPoints = 0;
	
	// Mount the camera to the active character.
	if ($sceneWindowMountParent != $playerSquad[$activeCharacter])
	{//echo("MOUNTING!");
		sceneWindow2D.mount($playerSquad[$activeCharacter], $sceneWindow2DxOffset SPC $sceneWindow2DyOffset, $cameraMountForce, false);		// Parameter list is: object to mount to, offset, force, do not send to mount!
		$sceneWindowMountParent = $playerSquad[$activeCharacter];
	}
}