// Handles Squad Member Talents.
// Worthless Bums 2012.


function initializeTalentActionPointCosts ()
{//echo("initializeTalentActionPointCosts()";
	// Leader Talent Action Point Costs.
	$chargeAPCost = 3;
	$snapShotsAPCost = 2;
	$radarAPCost = 3;
	$stimAPCost = 3;
		$squadStimDamageBoost = 2;
		$squadStimAccuracyBoost = 5;
	// Leader passive talent values.
	$ironResolveReduction = 25;
	$flakRoundsReduction = 1;
	$fireFighterReduction = 25;
	$vigilanceEvasion = 10;
	
	$bashAPCost = 3;
	$shieldAPCost = 4;
	$rallyAPCost = 4;
	$drillAPCost = 5;
	$formationAPCost = 2;
	$coveringFireAPCost = 4;
	$suppressionFireAPCost = 4;
	$dummySuitAPCost = 3;
	$sentryTurretAPCost = 3;
	$pullRankAPCost = 6;
	$repositionAPCost = 3;
	$taggedAPCost = 3;
	$tacticsAPCost = 3;
	
	// Scout Talent Action Point Costs.
	$scopedAPCost = 3;
		$scopedAccuracyBoost = 100;
		$scopedDamageBoost = 2;
	$calledShotAPCost = 3;
		$caledShotAPDeduction = 1;
	$garroteAPCost = 3;
		$garroteDamage = 10;
	$stasisAPCost = 4;
	// Scout passive talent values.
	$secondSkinAPRatio = 50;
	$stealthyEvasion = 10;
	$autoloaderLoadCost = 1;
	$biohazardDamageBoost = 2;
	
	$ricochetAPCost = 3;
	$smokeAPCost = 3;
	$spotterAPCost = 3;
	$defensePlanAPCost = 1;
	$escapePlanAPCost = 7;
	$disengageAPCost = 3;
	$trickShotAPCost = 3;
	$chargeShotAPCost = 3;
	$leapfrogAPCost = 3;
	$sabotageAPCost = 5;
	$pathfinderAPCost = 7;
	$endlessRoundAPCost = 1;
	
	// Grenadier Talent Action Point Costs.
	$napalmAPCost = 2;
	$batterAPCost = 2;
	$pincerAPCost = 2;
		$pincerARReduction = 1;
	$empAPCost = 3;
		$EmpDamage = 9;
		$EmpRange = 18.0;
	// Grenadier passive talent values.
	$ablativeArmorReduction = 25;
	
	$focusShotAPCost = 2;
	$shrapnelAPCost = 3;
	$gutShotAPCost = 3;
	$flankAPCost = 3;
	$ambushAPCost = 3;
	$assaultAPCost = 3;
	$earthquakeAPCost = 4;
	$shellChockAPCost = 3;
	$bombTurretAPCost = 3;
	$mayhemAPCost = 3;
	$pandemoniumAPCost = 6;
	$shapedChargeAPCost = 5;
	$claymoreAPCost = 4;
	
	// Support Talent Action Point Costs.
	$pointBlankAPCost = 2;
		$pointBlankArmorReduction = 50;
	$hailMaryAPCost = 2;
		$hailMaryAccuracyBoost = 10;
		$hailMaryRangeBoost = 2;
	$bulwarkAPCost = 3;
	$turretAPCost = 4;
		$squadTurretAmmoCost = 2;
	// Support passive talent values.
	$sharkRoundsIgnoreArmor = 50;
	
	$bunkerDownAPCost = 3;
	$sprayFireAPCost = 3;
	$perforateAPCost = 3;
	$dismantleAPCost = 3;
	$doubleTapAPCost = 4;
	
	// Engineer Talent Action Point Costs.
	$targetScanAPCost = 3;
	$magFistAPCost = 2;
	$weldAPCost = 2;
		$weldARCost = 1;
		$weldHealthGain = 2;
	$ammosmithAPCost = 3;
		$ammosmithGrenadeCost = 2;		// Don't expose this yet!
		$ammosmithAmmoGain = 1;			// Don't expose this yet!
	// Engineer passive talent values.
	$stunShotsDamageBoost = 2;
	$activeTargetingAccuracyBoost = 15;
	$techUpgradeLaserModAccuracyBoost = 10;
	$techUpgradePlasmaModDamageBoost = 4;
	
	$squadMagFist = false;
}
function keepTalent ()
{//echo("keepTalent()");
	$playerSquad[$activeCharacter].talents = setWord($playerSquad[$activeCharacter].talents, $selectedTalent, "1");
	popPromotionConfirmationGui();
	updateTalentBarIcons();
	Canvas.popDialog(promotionGui);
	Canvas.pushDialog(promotionGui);
}
function leaveTalent ()
{//echo("leaveTalent()");
	$selectedTalent = -1;
	popPromotionGui();
	updateTalentBarIcons();
}


//---------------------------------------------------
// Leader Class Talent Implementations.
//---------------------------------------------------
function snapShots ()
{//echo("snapShots()");
	if (!characterHasRequiredAmmo(0, 4))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Snap Shots" @ $defaultColor @ "!");
		return;
	}
	if ($playerSquad[$activeCharacter].currentActionPoints < $snapShotsAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Snap Shots" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $snapShotsAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Snap Shots" @ $defaultColor @ "!");
	}
	%originalActionPoints = $playerSquad[$activeCharacter].currentActionPoints;
	$playerSquad[$activeCharacter].currentActionPoints = 7;
	fireWeaponInDirection($northDirection);
	fireWeaponInDirection($southDirection);
	fireWeaponInDirection($eastDirection);
	fireWeaponInDirection($westDirection);
	$playerSquad[$activeCharacter].currentActionPoints = %originalActionPoints;
	scrollFloatingText($playerSquad[$activeCharacter], "SNAP SHOTS", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function bash ()
{//echo("bash()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $bashAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Bash" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $bashAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Bash" @ $defaultColor @ "!");
	}
	createSquadPowerBashAnimation();
	%range = 4.0;
	%characterPosition = $playerSquad[$activeCharacter].getPosition();
	for (%i = 0; %i < $monsterList.getCount(); %i++)
	{
		%monster = $monsterList.getObject(%i);
		%monsterPosition = %monster.getPosition();
		%distance = VectorDist(%characterPosition, %monsterPosition);
		if (%distance <= %range)
		{
			characterBashMonster(%i);
		}
	}
	playAudio("Audio:squadPowerBash", EffectsAudioVolume.value);
	scrollFloatingText($playerSquad[$activeCharacter], "BASH", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function shield ()
{//echo("shield()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $shieldAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Shield" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $shieldAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Shield" @ $defaultColor @ "!");
	}
	createSquadPowerShieldAnimation();
	initSquadPowerShieldCooldown();
	playAudio("Audio:squadPowerShield", EffectsAudioVolume.value);
	scrollFloatingText($playerSquad[$activeCharacter], "SHIELD", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function charge ()
{//echo("charge()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $chargeAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Charge" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $chargeAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Charge" @ $defaultColor @ "!");
	}
	%character = $playerSquad[$activeCharacter];
	%direction = %character.facing;
	%range = 3;
	chargeInDirection(%character, %direction, %range, 0);
	$fogOfWar.showFogOfWar();
	scrollFloatingText($playerSquad[$activeCharacter], "CHARGE", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function rally ()
{//echo("rally()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $rallyAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Rally" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $rallyAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Rally" @ $defaultColor @ "!");
	}
	if ($scoutPersist)
	{
		$playerSquad[$activeCharacter].currentActionPoints += 2;
		if ($playerSquad[$activeCharacter].currentActionPoints > $playerSquad[$activeCharacter].maxActionPoints)
		{
			$playerSquad[$activeCharacter].currentActionPoints = $playerSquad[$activeCharacter].maxActionPoints;
		}
		if (isSquadMemberParalyzed(1))
		{
			removeParalyzeSquadMember(1);
		}
	}
	if ($grenadierPersist)
	{
		$playerSquad[$activeCharacter].currentActionPoints += 2;
		if ($playerSquad[$activeCharacter].currentActionPoints > $playerSquad[$activeCharacter].maxActionPoints)
		{
			$playerSquad[$activeCharacter].currentActionPoints = $playerSquad[$activeCharacter].maxActionPoints;
		}
		if (isSquadMemberParalyzed(2))
		{
			removeParalyzeSquadMember(2);
		}
	}
	if ($supportPersist)
	{
		$playerSquad[$activeCharacter].currentActionPoints += 2;
		if ($playerSquad[$activeCharacter].currentActionPoints > $playerSquad[$activeCharacter].maxActionPoints)
		{
			$playerSquad[$activeCharacter].currentActionPoints = $playerSquad[$activeCharacter].maxActionPoints;
		}
		if (isSquadMemberParalyzed(3))
		{
			removeParalyzeSquadMember(3);
		}
	}
	scrollFloatingText($playerSquad[$activeCharacter], "SHIELD", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function stim ()
{//echo("stim()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $stimAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Stim" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $stimAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Stim" @ $defaultColor @ "!");
	}
	$squadStim = true;
	scrollFloatingText($playerSquad[$activeCharacter], "STIM", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function drill ()
{//echo("drill()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $drillAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Drill" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $drillAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Drill" @ $defaultColor @ "!");
	}
	clearSquadStatusEffects();
	initializeReadout();
	autoSwitchSquadmember();
}
function formation ()
{//echo("formation()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $formationAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Formation" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $formationAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Formation" @ $defaultColor @ "!");
	}
	$squadFormation = true;
	scrollFloatingText($playerSquad[$activeCharacter], "DRILL", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function coveringFire ()
{//echo("coveringFire()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $coveringFireAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Covering Fire" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $coveringFireAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Covering Fire" @ $defaultColor @ "!");
	}
	$squadCoveringFire = true;
	if ($squadCoveringFire	&&
		$leaderPersist)
	{
		for (%i = 0; %i < $monsterList.getCount(); %i++)
		{
			%monster = $monsterList.getObject(%i);
			if (objectWithinRange(%monster.getPosition(), $playerSquad[$activeCharacter].getPosition(), $squadCoveringFireRange))
			{
				%monster.currentActionPoints--;
			}
		}
		$squadCoveringFire = false;
	}
	scrollFloatingText($playerSquad[$activeCharacter], "COVERING FIRE", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function suppressionFire ()
{//echo("suppressionFire()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $suppressionFireAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Suppression Fire" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $suppressionFireAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Suppression Fire" @ $defaultColor @ "!");
	}
	$squadSuppressionFire = true;
	scrollFloatingText($playerSquad[$activeCharacter], "SUPPRESSION FIRE", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function dummySuit ()
{//echo("dummySuit()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $dummySuitAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Dummy Suit" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $dummySuitAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Dummy Suit" @ $defaultColor @ "!");
	}
	$squadDummySuit = true;
	scrollFloatingText($playerSquad[$activeCharacter], "DUMMY SUIT", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function sentryTurret ()
{//echo("sentryTurret()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $sentryTurretAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Sentry Turret" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $sentryTurretAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Sentry Turret" @ $defaultColor @ "!");
	}
	$squadSentryTurret = true;
	scrollFloatingText($playerSquad[$activeCharacter], "SENTRY TURRET", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function pullRank ()
{//echo("pullRank()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $pullRankAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Pull Rank" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $pullRankAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Pull Rank" @ $defaultColor @ "!");
	}
	if ($scoutPersist)
	{
		$playerSquad[$activeCharacter].currentActionPoints += 4;
		if ($playerSquad[$activeCharacter].currentActionPoints > $playerSquad[$activeCharacter].maxActionPoints)
		{
			$playerSquad[$activeCharacter].currentActionPoints = $playerSquad[$activeCharacter].maxActionPoints;
		}
	}
	if ($grenadierPersist)
	{
		$playerSquad[$activeCharacter].currentActionPoints += 4;
		if ($playerSquad[$activeCharacter].currentActionPoints > $playerSquad[$activeCharacter].maxActionPoints)
		{
			$playerSquad[$activeCharacter].currentActionPoints = $playerSquad[$activeCharacter].maxActionPoints;
		}
	}
	if ($supportPersist)
	{
		$playerSquad[$activeCharacter].currentActionPoints += 4;
		if ($playerSquad[$activeCharacter].currentActionPoints > $playerSquad[$activeCharacter].maxActionPoints)
		{
			$playerSquad[$activeCharacter].currentActionPoints = $playerSquad[$activeCharacter].maxActionPoints;
		}
	}
	scrollFloatingText($playerSquad[$activeCharacter], "PULL RANK", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function reposition ()
{//echo("reposition()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $repositionAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Reposition" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $repositionAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Reposition" @ $defaultColor @ "!");
	}
	$squadReposition = true;
	$playerSquad[$activeCharacter].currentActionPoints = 7;
	$playerSquad[$activeCharacter].currentActionPoints = 7;
	$playerSquad[$activeCharacter].currentActionPoints = 7;
	$playerSquad[$activeCharacter].currentActionPoints = 7;
	scrollFloatingText($playerSquad[$activeCharacter], "REPOSITION", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function tagged ()
{//echo("tagged()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $taggedAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Tagged" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $taggedAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Tagged" @ $defaultColor @ "!");
	}
	$squadTagged = true;
	scrollFloatingText($playerSquad[$activeCharacter], "TAGGED", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function tactics ()
{//echo("tactics()");
	if ($playerSquad[$activeCharacter].currentActionPoints < $tacticsAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Tactics" @ $defaultColor @ "!");
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $tacticsAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Tactics" @ $defaultColor @ "!");
	}
	$squadTactics = true;
	scrollFloatingText($playerSquad[$activeCharacter], "TACTICS", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}


//---------------------------------------------------
// Scout Class Talent Implementations.
//---------------------------------------------------
function scoped ()
{//echo("scoped()");
	if (!characterHasRequiredAmmo(1, 1))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Scoped" @ $defaultColor @ "!");
		
		return;
	}
	
	// Make sure the Scout has enough Action Points to use Scoped!
	if ($playerSquad[$activeCharacter].currentActionPoints < $scopedAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Scoped" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $scopedAPCost;
		$playerSquad[$activeCharacter].currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Scoped" @ $defaultColor @ "!");
	}
	
	// Perform Scoped.
	// Flag Scoped status!
	$squadScoped = true;
	// Temporarily boost Scout accuracy and damage.
	%originalScoutAccuracy = ($playerSquad[$activeCharacter].weapon).accuracy;
	if (($playerSquad[$activeCharacter].weapon).accuracy < 100)
	{
		($playerSquad[$activeCharacter].weapon).accuracy = 100;
	}
	%originalScoutDamage = ($playerSquad[$activeCharacter].weapon).damage;
	($playerSquad[$activeCharacter].weapon).damage *= 2;
	// Fire in facing direction.
	fireWeaponInDirection($playerSquad[$activeCharacter].facing);
	// Reset Scout weapon stats.
	($playerSquad[$activeCharacter].weapon).accuracy = %originalScoutAccuracy;
	($playerSquad[$activeCharacter].weapon).damage = %originalScoutDamage;
	// Unflag Scoped status!
	schedule(200, 0, "unflagScoped");
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "SCOPED", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function unflagScoped ()
{
	$squadScoped = false;
}
function ricochet ()
{//echo("ricochet()");
	if (!characterHasRequiredAmmo(1, 1))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Ricochet" @ $defaultColor @ "!");
		
		return;
	}
	
	// Make sure the Scout has enough Action Points to use Ricochet!
	if ($playerSquad[$activeCharacter].currentActionPoints < $ricochetAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Ricochet" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $ricochetAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Ricochet" @ $defaultColor @ "!");
	}
	
	// Flag Ricochet status!
	$squadRicochet = true;
	// Execute Ricochet attack.
	//fireWeaponInDirection($playerSquad[$activeCharacter].facing);
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "RICOCHET", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function radar ()
{//echo("radar()");
	// Make sure the Scout has enough Action Points to use Radar!
	if ($playerSquad[$activeCharacter].currentActionPoints < $radarAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Radar" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $radarAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Radar" @ $defaultColor @ "!");
	}
	
	// Use Radar.
	useRadar();
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "RADAR", "talent");
	// Initialize readout.
	initializeReadout();
	// Update floating AP texts.
	updateSquadMemberFloatingActionPoints();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function smoke ()
{//echo("smoke()");
	// Make sure the Scout has enough Action Points to use Smoke!
	if ($playerSquad[$activeCharacter].currentActionPoints < $radarAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Smoke" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $radarAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Smoke" @ $defaultColor @ "!");
	}
	
	// Use Smoke.
	tpe();
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "SMOKE", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function spotter ()
{//echo("spotter()");
	// Make sure the Scout has enough Action Points to use Spotter!
	if ($playerSquad[$activeCharacter].currentActionPoints < $spotterAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Spotter" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $spotterAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Spotter" @ $defaultColor @ "!");
	}
	
	// Use Spotter.
	$squadSpotter = true;
	
	// Check fog of war.
	$fogOfWar.showFogOfWar();
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "SPOTTER", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function calledShot ()
{//echo("calledShot()");
	if (!characterHasRequiredAmmo(1, 1))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Called Shot" @ $defaultColor @ "!");
		
		return;
	}
	
	// Make sure the Scout has enough Action Points to use Called Shot!
	if ($playerSquad[$activeCharacter].currentActionPoints < $calledShotAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Called Shot" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $calledShotAPCost;
		$playerSquad[$activeCharacter].currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Called Shot" @ $defaultColor @ "!");
	}
	
	// Use Called Shot.
	$squadCalledShot = true;
	fireWeaponInDirection($playerSquad[$activeCharacter].facing);
	
	// Update monsters' floating text.
	updateMonsterFloatingText();
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "CALLED SHOT", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function defensePlan ()
{//echo("defensePlan()");
	// Make sure the Scout has enough Action Points to use Defense Plan!
	if ($playerSquad[$activeCharacter].currentActionPoints < $defensePlanAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Defense Plan" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $defensePlanAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Defense Plan" @ $defaultColor @ "!");
	}
	
	// Use Defense Plan.
	$squadDefensePlan = true;
	$squadDefensePlanPoints = $playerSquad[$activeCharacter].currentActionPoints;
	$playerSquad[$activeCharacter].currentActionPoints = 0;
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "DEFENSE PLAN", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function escapePlan ()
{//echo("escapePlan()");
	// Make sure the Scout has enough Action Points to use Escape Plan!
	if ($playerSquad[$activeCharacter].currentActionPoints < $defensePlanAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Escape Plan" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $defensePlanAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Escape Plan" @ $defaultColor @ "!");
	}
	
	// Use Escape Plan.
	moveSquadToFreeArea();
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "ESCAPE PLAN", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function garrote ()
{//echo("garrote()");
	// Grab monster.
	%monsterIndex = getAdjacentFacingMonster($playerSquad[$activeCharacter]);
	%monster = $monsterList.getObject(%monsterIndex);// Make sure we have a valid Garrote target!
	if (%monsterIndex == -1)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name @ $whiteColor @ " has no target to Garrote" @ $defaultColor @ "!");
		
		return;
	}
	// Make sure monster is facing away from squad member!
	if ($playerSquad[$activeCharacter].facing != %monster.facing)
	{
		updateEventText($whiteColor @ "Garrote target not facing away" @ $defaultColor @ "!");
		
		return;
	}
	
	// Make sure the Scout has enough Action Points to use Garrote!
	if ($playerSquad[$activeCharacter].currentActionPoints < $garroteAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Garrote" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $garroteAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Garrote" @ $defaultColor @ "!");
	}
	
	// Use Garrote.
	%damage = $garroteDamage;
	if (%monster.currentHealth <= %damage)
	{
		// Set new monster health.
		%monster.currentHealth = 0;
		
		// Check if this monster is a robot.
		if (%monster.isRobot)
		{
			// Trigger Armor repair.
			triggerArmorRepair();
		}
		
		// Update kill record.
		updateKillRecord($activeCharacter, %monster.name, %monster.level);
		// Kill the monster.
		handleMonsterDeath($activeCharacter, %monsterIndex);
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC %damageColor @ "kills" SPC $monsterColor @ %monster.name @ $defaultColor @ "!");
	}
	else
	{
		// Set new monster health.
		%monster.currentHealth -= %damage;
	}
	%direction = $playerSquad[$activeCharacter].facing;
	monsterHit(%monsterIndex, %damage, %direction, "garrote");
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "GARROTE", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function disengage ()
{//echo("disengage()");
	// Make sure the Scout has enough Action Points to use Disengage!
	if ($playerSquad[$activeCharacter].currentActionPoints < $garroteAPCost)
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more AP to use Disengage" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		$playerSquad[$activeCharacter].currentActionPoints -= $garroteAPCost;
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Disengage" @ $defaultColor @ "!");
	}
	
	// Use Disengage.
	// Nothing here yet!
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "DISENGAGE", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function trickShot ()
{//echo("trickShot()");
	if (!characterHasRequiredAmmo(1, 1))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Trick Shot" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Scout.
	%scout = $playerSquad[$activeCharacter];
	
	// Make sure the Scout has enough Action Points to use Trick Shot!
	if (%scout.currentActionPoints < $trickShotAPCost)
	{
		updateEventText($squadColor @ %scout.name SPC $whiteColor @ "needs more AP to use Trick Shot" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		%scout.currentActionPoints -= $trickShotAPCost;
		$playerSquad[$activeCharacter].currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %scout.name SPC $friendlyActionColor @ "uses Trick Shot" @ $defaultColor @ "!");
	}
	
	// Use Trick Shot.
	$squadTrickShot = true;
	// Fire in facing direction.
	fireWeaponInDirection(%scout.facing);
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "TRICK SHOT", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function chargeShot ()
{//echo("chargeShot()");
	if (!characterHasRequiredAmmo(1, 1))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Charge Shot" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Scout.
	%scout = $playerSquad[$activeCharacter];
	
	// Make sure the Scout has enough Action Points to use Charge Shot!
	if (%scout.currentActionPoints < $chargeShotAPCost)
	{
		updateEventText($squadColor @ %scout.name SPC $whiteColor @ "needs more AP to use Charge Shot" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		%scout.currentActionPoints -= $chargeShotAPCost;
		$playerSquad[$activeCharacter].currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %scout.name SPC $friendlyActionColor @ "uses Charge Shot" @ $defaultColor @ "!");
	}
	
	// Use Charge Shot.
	$squadChargeShot = true;
	// Fire in facing direction.
	fireWeaponInDirection(%scout.facing);
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "CHARGE SHOT", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function leapfrog ()
{//echo("leapfrog()");
	// Grab the Scout.
	%scout = $playerSquad[$activeCharacter];
	
	// Check if we can use Leapfrog.
	%xIndex = %scout.xIndex;
	%yIndex = %scout.yIndex;
	%x = %xIndex;
	%y = %yIndex;
	switch$ (%scout.facing)
	{
		case $northDirection:	%yIndex -= 2;%y -= 1;
		case $southDirection:	%yIndex += 2;%y += 1;
		case $westDirection:	%xIndex -= 2;%x -= 1;
		case $eastDirection:	%xIndex += 2;%x += 1;
	}
	// Make sure we don't jump over wall obstacles!
	if (isObject($mazeRoom[%x, %y]))
	{
		// NOTE: May wish to change this to just non-wall tiles so we can jump over outer space tiles!
		if ($mazeRoom[%x, %y].status != -4)
		{
			return;
		}
	}
	// Check if that tile is free.
	if (!tileIsClear(%xIndex, %yIndex))
	{
		
		return;
	}
	
	// Make sure the Scout has enough Action Points to use Leapfrog!
	if (%scout.currentActionPoints < $leapfrogAPCost)
	{
		updateEventText($squadColor @ %scout.name SPC $whiteColor @ "needs more AP to use Leapfrog" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		%scout.currentActionPoints -= $leapfrogAPCost;
		updateEventText($squadColor @ %scout.name SPC $friendlyActionColor @ "uses Leapfrog" @ $defaultColor @ "!");
	}
	
	// Use Leapfrog.
	// Convert indices to position.
	%position = getTilePositionFromIndices(%xIndex, %yIndex);
	// Grow and shrink Scout!
	growAndShrinkUnit(%scout, 10.0, 240.0);	// Somewhat arbitrarily chosen values...
	// Move scout to that tile.
	moveUnit(%scout, getWord(%position, 0), getWord(%position, 1), 20.0, true, true, true, 0.0, false);
	// Enforce new Scout position.
	%scout.xIndex = %xIndex;
	%scout.yIndex = %yIndex;
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "LEAPFROG", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function sabotage ()
{//echo("sabotage()");
	// Grab the Scout.
	%scout = $playerSquad[$activeCharacter];
	
	// Make sure the Scout has enough Action Points to use Sabotage!
	if (%scout.currentActionPoints < $sabotageAPCost)
	{
		updateEventText($squadColor @ %scout.name SPC $whiteColor @ "needs more AP to use Sabotage" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		%scout.currentActionPoints -= $sabotageAPCost;
		updateEventText($squadColor @ %scout.name SPC $friendlyActionColor @ "uses Sabotage" @ $defaultColor @ "!");
	}
	
	// Use Sabotage.
	%sabotageRange = 30.0;
	for (%i = 0; %i < $monsterList.getCount(); %i++)
	{
		// Get monster.
		%monster = $monsterList.getObject(%i);
		// Check if this monster is mechanical.
		if (%monster.creatureType $= "mechanical")
		{
			// Calculate distance.
			%distance = VectorDist(%scout.getPosition(), %monster.getPosition());
			if (%distance <= %sabotageRange)
			{
				// Stun this monster!
				if (%monster.currentActionPoints > 0)
				{
					%monster.currentActionPoints--;
				}
				
				// Stun animation!
				// Nothing here yet!
			}
		}
	}
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "SABOTAGE", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function pathfinder ()
{//echo("pathfinder()");
	// Grab the Scout.
	%scout = $playerSquad[$activeCharacter];
	
	// Make sure the Scout has enough Action Points to use Pathfinder!
	if (%scout.currentActionPoints < $sabotageAPCost)
	{
		updateEventText($squadColor @ %scout.name SPC $whiteColor @ "needs more AP to use Pathfinder" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		%scout.currentActionPoints -= $sabotageAPCost;
		updateEventText($squadColor @ %scout.name SPC $friendlyActionColor @ "uses Pathfinder" @ $defaultColor @ "!");
	}
	
	// Use Pathfinder.
	traceStairs();
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "PATHFINDER", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function endlessRound ()
{//echo("endlessRound()");
	// Grab the Scout.
	%scout = $playerSquad[$activeCharacter];
	
	// Make sure Scout meets requirements to use Endless Round!
	if (%scout.ammo > 0)
	{
		updateEventText($squadColor @ %scout.name SPC $whiteColor @ " can only use Endless Round without ammo" @ $defaultColor @ "!");
		
		return;
	}
	
	// Make sure the Scout has enough Action Points to use Endless Round!
	if (%scout.currentActionPoints < $endlessRoundAPCost)
	{
		updateEventText($squadColor @ %scout.name SPC $whiteColor @ "needs more AP to use Endless Round" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		%scout.currentActionPoints -= $endlessRoundAPCost;
		updateEventText($squadColor @ %scout.name SPC $friendlyActionColor @ "uses Endless Round" @ $defaultColor @ "!");
	}
	
	// Use Endless Round.
	%scout.ammo = 1;
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "ENDLESS ROUND", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function stasis ()
{//echo("stasis()");
	if (!characterHasRequiredAmmo(1, 1))
	{
		// Not enough ammo to use talent!
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Stasis" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Scout.
	%scout = $playerSquad[$activeCharacter];
	
	// Make sure the Scout has enough Action Points to use Stasis!
	if (%scout.currentActionPoints < $stasisAPCost)
	{
		updateEventText($squadColor @ %scout.name SPC $whiteColor @ "needs more AP to use Stasis" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		%scout.currentActionPoints -= $stasisAPCost;
		$playerSquad[$activeCharacter].currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %scout.name SPC $friendlyActionColor @ "uses Stasis" @ $defaultColor @ "!");
	}
	
	// Use Stasis.
	$squadStasis = true;
	// Fire in facing direction.
	fireWeaponInDirection(%scout.facing);
	
	// Scroll talent text.
	scrollFloatingText($playerSquad[$activeCharacter], "STASIS", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}



//---------------------------------------------------
// Grenadier Class Talent Implementations.
//---------------------------------------------------
function focusShot ()
{//echo("focusShot()");
	if (!characterHasRequiredAmmo(2, 1))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Focus Shot" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Focus Shot!
	if (%grenadier.currentActionPoints < $focusShotAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Focus Shot" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $focusShotAPCost;
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Focus Shot" @ $defaultColor @ "!");
	}
	
	// Perform Focus Shot.
	$squadFocusShot = true;
	// Fire in facing direction.
	fireWeaponInDirection(%grenadier.facing);
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "FOCUS SHOT", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function shrapnel ()
{//echo("shrapnel()");
	if (!characterHasRequiredAmmo(2, 1))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Shrapnel" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Shrapnel!
	if (%grenadier.currentActionPoints < $shrapnelAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Shrapnel" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $shrapnelAPCost;
		%grenadier.currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Shrapnel" @ $defaultColor @ "!");
	}
	
	// Perform Shrapnel.
	$squadShrapnel = true;
	// Fire in facing direction.
	fireWeaponInDirection(%grenadier.facing);
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "SHRAPNEL", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function gutShot ()
{//echo("gutShot()");
	if (!characterHasRequiredAmmo(2, 1))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Gut Shot" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Gut Shot!
	if (%grenadier.currentActionPoints < $gutShotAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Gut Shot" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $gutShotAPCost;
		%grenadier.currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Gut Shot" @ $defaultColor @ "!");
	}
	
	// Perform Gut Shot.
	$squadGutShot = true;
	// Fire in facing direction.
	fireWeaponInDirection(%grenadier.facing);
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "GUT SHOT", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function flank ()
{//echo("flank()");
	if (!characterHasRequiredAmmo(2, 1))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Flank" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Flank!
	if (%grenadier.currentActionPoints < $flankAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Flank" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $flankAPCost;
		%grenadier.currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Flank" @ $defaultColor @ "!");
	}
	
	// Perform Flank.
	$squadFlank = true;
	// Fire in facing direction.
	fireWeaponInDirection(%grenadier.facing);
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "FLANK", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function pincer ()
{//echo("pincer()");
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Pincer!
	if (%grenadier.currentActionPoints < $pincerAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Pincer" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $pincerAPCost;
		%grenadier.currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Pincer" @ $defaultColor @ "!");
	}
	
	// Perform Pincer.
	$squadPincher = true;
	// Move in the facing direction.
	moveCharacter($activeCharacter, %grenadier.facing);
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "PINCER", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function ambush ()
{//echo("ambush()");
	if (!characterHasRequiredAmmo(2, 1))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Ambush" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Ambush!
	if (%grenadier.currentActionPoints < $ambushAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Ambush" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $ambushAPCost;
		%grenadier.currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Ambush" @ $defaultColor @ "!");
	}
	
	// Perform Ambush.
	$squadAmbush = true;
	// Fire in facing direction.
	fireWeaponInDirection(%grenadier.facing);
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "AMBUSH", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function assault ()
{//echo("assault()");
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Assault!
	if (%grenadier.currentActionPoints < $assaultAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Assault" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $assaultAPCost;
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Assault" @ $defaultColor @ "!");
	}
	
	// Perform Assault.
	$squadAssault = true;
	// Move in the facing direction.
	moveCharacter($activeCharacter, %grenadier.facing);
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "ASSAULT", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function napalm ()
{//echo("napalm()");
	if (!characterHasRequiredAmmo(2, 1))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Napalm" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Napalm!
	if (%grenadier.currentActionPoints < $napalmAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Napalm" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $napalmAPCost;
		%grenadier.currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Napalm" @ $defaultColor @ "!");
	}
	
	// Perform Napalm.
	$squadNapalm = true;
	// Fire in facing direction.
	fireWeaponInDirection(%grenadier.facing);
	// End Napalm.
	//$squadNapalm = false;
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "NAPALM", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function earthquake ()
{//echo("earthquake()");
	if (!characterHasRequiredAmmo(2, 1))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Earthquake" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Earthquake!
	if (%grenadier.currentActionPoints < $earthquakeAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Earthquake" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $earthquakeAPCost;
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Earthquake" @ $defaultColor @ "!");
	}
	
	// Perform Earthquake.
	$squadEarthquake = true;
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "EARTHQUAKE", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function shellShock ()
{//echo("shellShock()");
	if (!characterHasRequiredAmmo(2, 1))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Shell Shock" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Shell Shock!
	if (%grenadier.currentActionPoints < $shellShockAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Shell Shock" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $shellShockAPCost;
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Shell Shock" @ $defaultColor @ "!");
	}
	
	// Perform Shell Shock.
	$squadShellShock = true;
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "SHELL SHOCK", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function bombTurret ()
{//echo("bombTurret()");
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Bomb Turret!
	if (%grenadier.currentActionPoints < $bombTurretAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Bomb Turret" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $bombTurretAPCost;
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Bomb Turret" @ $defaultColor @ "!");
	}
	
	// Perform Bomb Turret.
	$squadBombTurret = true;
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "BOMB TURRET", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function mayhem ()
{//echo("mayhem()");
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Mayhem!
	if (%grenadier.currentActionPoints < $mayhemAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Mayhem" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $mayhemAPCost;
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Mayhem" @ $defaultColor @ "!");
	}
	
	// Perform Mayhem.
	$squadMayhem = true;
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "MAYHEM", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function pandemonium ()
{//echo("pandemonium()");
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Pandemonium!
	if (%grenadier.currentActionPoints < $pandemoniumAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Pandemonium" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $pandemoniumAPCost;
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Pandemonium" @ $defaultColor @ "!");
	}
	
	// Perform Pandemonium.
	$squadPandemonium = true;
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "PANDEMONIUM", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function emp ()
{//echo("emp()");
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use EMP!
	if (%grenadier.currentActionPoints < $empAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use EMP" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $empAPCost;
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses EMP" @ $defaultColor @ "!");
	}
	
	// Perform EMP.
	//$squadEMP = true;
	// Find robots in range and smack them!
	for (%i = 0; %i < $monsterList.getCount(); %i++)
	{
		%monster = $monsterList.getObject(%i);
		if (VectorDist(%grenadier.getPosition(), %monster.getPosition()) <= $EmpRange)
		{
			monsterHit(%i, $EmpDamage, %monster.facing, "electricity");
		}
	}
	// Play EMP sound effect.
	playAudio("Audio:emp", EffectsAudioVolume.value);
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "EMP", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function batter ()
{//echo("batter()");
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Batter!
	if (%grenadier.currentActionPoints < $batterAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Batter" @ $defaultColor @ "!");
		return;
	}
	else
	{
		%grenadier.currentActionPoints -= $batterAPCost;
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Batter" @ $defaultColor @ "!");
	}
	
	// Perform Batter.
	%xIndex = $playerSquad[$activeCharacter].xIndex;
	%yIndex = $playerSquad[$activeCharacter].yIndex;
	%monster = getMonsterAtIndices(%xIndex, %yIndex - 1);		// North tile.
	if (isObject(%monster))
	{
		knockBackUnit(%monster, $northDirection);
	}
	%monster = getMonsterAtIndices(%xIndex, %yIndex + 1);		// South tile.
	if (isObject(%monster))
	{
		knockBackUnit(%monster, $southDirection);
	}
	%monster = getMonsterAtIndices(%xIndex + 1, %yIndex);		// East tile.
	if (isObject(%monster))
	{
		knockBackUnit(%monster, $eastDirection);
	}
	%monster = getMonsterAtIndices(%xIndex - 1, %yIndex);		// West tile.
	if (isObject(%monster))
	{
		knockBackUnit(%monster, $westDirection);
	}
	// Grow and shrink!
	inPlaceActionGrowAndShrink(%grenadier);
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "BATTER", "talent");
	// Initialize readout.
	initializeReadout();
	updateFloatingActionPointText($activeCharacter);
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function shapedCharge ()
{//echo("shapedCharge()");
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Shaped Charge!
	if (%grenadier.currentActionPoints < $shapedChargeAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Shaped Charge" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $shapedChargeAPCost;
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Shaped Charge" @ $defaultColor @ "!");
	}
	
	// Perform Shaped Charge.
	$squadShapedCharge = true;
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "SHAPED CHARGE", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function claymore ()
{//echo("claymore()");
	// Grab the Grenadier.
	%grenadier = $playerSquad[$activeCharacter];
	
	// Make sure the Grenadier has enough Action Points to use Claymore!
	if (%grenadier.currentActionPoints < $claymoreAPCost)
	{
		updateEventText($squadColor @ %grenadier.name SPC $whiteColor @ "needs more AP to use Claymore" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%grenadier.currentActionPoints -= $claymoreAPCost;
		updateEventText($squadColor @ %grenadier.name SPC $friendlyActionColor @ "uses Claymore" @ $defaultColor @ "!");
	}
	
	// Perform Claymore.
	$squadClaymore = true;
	
	// Scroll talent text.
	scrollFloatingText(%grenadier, "CLAYMORE", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}


//---------------------------------------------------
// Support Class Talent Implementations.
//---------------------------------------------------
function bunkerDown ()
{//echo("bunkerDown()");
	// Grab the Support.
	%support = $playerSquad[$activeCharacter];
	
	// Make sure the Support has enough Action Points to use Bunker Down!
	if (%support.currentActionPoints < $bunkerDownAPCost)
	{
		updateEventText($squadColor @ %support.name SPC $whiteColor @ "needs more AP to use Bunker Down" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%support.currentActionPoints -= $bunkerDownAPCost;
		updateEventText($squadColor @ %support.name SPC $friendlyActionColor @ "uses Bunker Down" @ $defaultColor @ "!");
	}
	
	// Perform Bunker Down.
	$squadBunkerDown = true;
	
	// Scroll talent text.
	scrollFloatingText(%SUPPORT, "BUNKER DOWN", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function sprayFire ()
{//echo("sprayFire()");
	if (!characterHasRequiredAmmo(3, 3))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Spray Fire" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Support.
	%support = $playerSquad[$activeCharacter];
	
	// Make sure the Support has enough Action Points to use Spray Fire!
	if (%support.currentActionPoints < $sprayFireAPCost)
	{
		updateEventText($squadColor @ %support.name SPC $whiteColor @ "needs more AP to use Spray Fire" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%support.currentActionPoints -= $sprayFireAPCost;
		%support.currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %support.name SPC $friendlyActionColor @ "uses Spray Fire" @ $defaultColor @ "!");
	}
	
	// Perform Spray Fire.
	$squadSprayFire = true;
	// Fire in facing direction.
	fireWeaponInDirection(%support.facing);
	
	// Scroll talent text.
	scrollFloatingText(%SUPPORT, "SPRAY FIRE", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function bulwark ()
{//echo("bulwark()");
	// Grab the Support.
	%support = $playerSquad[$activeCharacter];
	
	// Get facing adjacent tile indices.
	switch (%support.facing)
	{
		case $northDirection:
			%xIndex = %support.xIndex;
			%yIndex = %support.yIndex - 1;
		case $southDirection:
			%xIndex = %support.xIndex;
			%yIndex = %support.yIndex + 1;
		case $westDirection:
			%xIndex = %support.xIndex - 1;
			%yIndex = %support.yIndex;
		case $eastDirection:
			%xIndex = %support.xIndex + 1;
			%yIndex = %support.yIndex;
	}
	// Check tile..
	if (isObject($mazeRoom[%xIndex, %yIndex])	||
		!tileIsClearOfUnits(%xIndex, %yIndex))
	{// Can't place Bulwark!
		updateEventText($squadColor @ %support.name SPC $whiteColor @ "can't place a Bulwark there!" @ $defaultColor @ "!");
		return;
	}
	
	// Make sure the Support has enough Action Points to use Bulwark!
	if (%support.currentActionPoints < $bulwarkAPCost)
	{
		updateEventText($squadColor @ %support.name SPC $whiteColor @ "needs more AP to use Bulwark" @ $defaultColor @ "!");
		return;
	}
	else
	{// Deduct action points.
		%support.currentActionPoints -= $bulwarkAPCost;
		updateEventText($squadColor @ %support.name SPC $friendlyActionColor @ "uses Bulwark" @ $defaultColor @ "!");
	}
	
	// Perform Bulwark.
	$squadBulwark = true;
	// Create wall sprite.
	%wallSprite = new Sprite("Wall")
	{
		status = -2;
		SceneLayer = $LiftedTileLayer;
		graph = $LiftedTileGraph;
		position = getWord(getTilePositionFromIndices(%xIndex, %yIndex), 0) SPC getWord(getTilePositionFromIndices(%xIndex, %yIndex), 1) + $GlobalVerticalShift;//getTilePositionFromIndices(%xIndex, %yIndex);
		scenegraph = levelSceneGraph;
		Image = getImageFromOverworldLocation();
		frame = 42;
		visible = true;
		size = "4 4";
		door = null;
		light = null;
		painting = null;
	};
	addObjectToScene(%wallSprite);
	$mazeRoom[%xIndex, %yIndex] = %wallSprite;
	playRandomHeavyMetalSfx();
	$fogOfWar.showFogOfWar();
	scrollFloatingText(%support, "BULWARK", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function pointBlank ()
{//echo("pointBlank()");
	if (!characterHasRequiredAmmo(3, 3))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Point Blank" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Support.
	%support = $playerSquad[$activeCharacter];
	
	// Make sure the Support has enough Action Points to use Point Blank!
	if (%support.currentActionPoints < $pointBlankAPCost)
	{
		updateEventText($squadColor @ %support.name SPC $whiteColor @ "needs more AP to use Point Blank" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%support.currentActionPoints -= $pointBlankAPCost;
		%support.currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %support.name SPC $friendlyActionColor @ "uses Point Blank" @ $defaultColor @ "!");
	}
	
	// Perform Point Blank.
	$squadPointBlank = true;
	// Fire in facing direction.
	fireWeaponInDirection(%support.facing);
	
	// Scroll talent text.
	scrollFloatingText(%support, "POINT BLANK", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function perforate ()
{//echo("perforate()");
	if (!characterHasRequiredAmmo(3, 3))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Perforate" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Support.
	%support = $playerSquad[$activeCharacter];
	
	// Make sure the Support has enough Action Points to use Perforate!
	if (%support.currentActionPoints < $perforateAPCost)
	{
		updateEventText($squadColor @ %support.name SPC $whiteColor @ "needs more AP to use Perforate" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%support.currentActionPoints -= $perforateAPCost;
		%support.currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %support.name SPC $friendlyActionColor @ "uses Perforate" @ $defaultColor @ "!");
	}
	
	// Perform Perforate.
	$squadPerforate = true;
	// Fire in facing direction.
	fireWeaponInDirection(%support.facing);
	
	// Scroll talent text.
	scrollFloatingText(%support, "PERFORATE", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function dismantle ()
{//echo("dismantle()");
	if (!characterHasRequiredAmmo(3, 3))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Dismantle" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Support.
	%support = $playerSquad[$activeCharacter];
	
	// Make sure the Support has enough Action Points to use Dismantle!
	if (%support.currentActionPoints < $dismantleAPCost)
	{
		updateEventText($squadColor @ %support.name SPC $whiteColor @ "needs more AP to use Dismantle" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%support.currentActionPoints -= $dismantleAPCost;
		%support.currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %support.name SPC $friendlyActionColor @ "uses Dismantle" @ $defaultColor @ "!");
	}
	
	// Perform Dismantle.
	$squadDismantle = true;
	// Fire in facing direction.
	fireWeaponInDirection(%support.facing);
	
	// Update monsters' floating text.
	updateMonsterFloatingText();
	
	// Scroll talent text.
	scrollFloatingText(%support, "DISMANTLE", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function doubleTap ()
{//echo("doubleTap()");
	if (!characterHasRequiredAmmo(3, 6))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Double Tap" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Support.
	%support = $playerSquad[$activeCharacter];
	
	// Make sure the Support has enough Action Points to use Double Tap!
	if (%support.currentActionPoints < $doubleTapAPCost)
	{
		updateEventText($squadColor @ %support.name SPC $whiteColor @ "needs more AP to use Double Tap" @ $defaultColor @ "!");
		
		return;
	}
	else
	{
		// Deduct action points.
		%support.currentActionPoints -= $doubleTapAPCost;
		%support.currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %support.name SPC $friendlyActionColor @ "uses Double Tap" @ $defaultColor @ "!");
	}
	
	// Perform Double Tap.
	$squadDoubleTap = true;
	// Fire in facing direction.
	fireWeaponInDirection(%support.facing);
	schedule(250, 0, "fireWeaponInDirection", %support.facing);
	
	// Scroll talent text.
	scrollFloatingText(%support, "DOUBLE TAP", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function hailMary ()
{//echo("hailMary()");
	if (!characterHasRequiredAmmo(3, 3))
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Hail Mary" @ $defaultColor @ "!");
		
		return;
	}
	
	// Grab the Support.
	%support = $playerSquad[$activeCharacter];
	
	// Make sure the Support has enough Action Points to use Hail Mary!
	if (%support.currentActionPoints < $hailMaryAPCost)
	{
		updateEventText($squadColor @ %support.name SPC $whiteColor @ "needs more AP to use Hail Mary" @ $defaultColor @ "!");
		return;
	}
	else
	{
		// Deduct action points.
		%support.currentActionPoints -= $hailMaryAPCost;
		%support.currentActionPoints++;		// Needed to fire!
		updateEventText($squadColor @ %support.name SPC $friendlyActionColor @ "uses Hail Mary" @ $defaultColor @ "!");
	}
	
	// Perform Hail Mary.
	$squadHailMary = true;
	// Fire in facing direction.
	fireWeaponInDirection(%support.facing);
	
	// Scroll talent text.
	scrollFloatingText(%support, "HAIL MARY", "talent");
	// Initialize readout.
	initializeReadout();
	// Check auto switch squad member.
	autoSwitchSquadmember();
}
function turret ()
{//echo("turret()");
	%support = $playerSquad[$activeCharacter];
	if (%support.ammo < $squadTurretAmmoCost)
	{updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $whiteColor @ "needs more ammo to use Turret" @ $defaultColor @ "!");
		return;
	}
	else
	{
		%support.ammo -= $squadTurretAmmoCost;
		playAudio("Audio:weaponSwap", EffectsAudioVolume.value);
		updateInventoryTabInformation();
	}
	// Make sure the Support has enough Action Points to use Turret!
	if (%support.currentActionPoints < $turretAPCost)
	{updateEventText($squadColor @ %support.name SPC $whiteColor @ "needs more AP to use Turret" @ $defaultColor @ "!");
		return;
	}
	else
	{updateEventText($squadColor @ %support.name SPC $friendlyActionColor @ "uses Turret" @ $defaultColor @ "!");
		%support.currentActionPoints -= $turretAPCost;
		%support.currentActionPoints++;		// Needed to fire!
	}
	// Perform Turret.
	// Create sentry turret.
	%weapon = %support.weapon;
	createSentryTurret(%support.xIndex, %support.yIndex, %weapon.damage, %weapon.range, %weapon.accuracy, %support.facing);
	// Update display guis.
	initializeReadout();
	updateSquadInfoGui();
	// Autoswitch squadmember if this character is out of action points.
	if (%support.currentActionPoints == 0)
	{
		autoSwitchSquadmember();
	}
	updateEventText($whiteColor @ "Sentry Turret dropped" @ $defaultColor @ "!");
	scrollFloatingText(%support, "TURRET", "talent");
	updateFirearmReloadReadout();
	autoSwitchSquadmember();
}


//---------------------------------------------------
// Engineer Class Talent Implementations.
//---------------------------------------------------
function targetScan ()
{//echo("targetScan()");
	%engineer = $playerSquad[$activeCharacter];
	if (%engineer.currentActionPoints < $targetScanAPCost)
	{updateEventText($squadColor @ %engineer.name SPC $whiteColor @ "needs more AP to use Target Scan" @ $defaultColor @ "!");
		return;
	}
	else
	{updateEventText($squadColor @ %engineer.name SPC $friendlyActionColor @ "uses Target Scan" @ $defaultColor @ "!");
		%engineer.currentActionPoints -= $targetScanAPCost;
	}
	// Perform Target Scan.
	for (%i = 0; %i < $MonsterList.getCount(); %i++)
	{
		%monster = $MonsterList.getObject(%i);
		if (%monster.visible)
		{
			%monster.scanned = true;
			createTargetScanAnimation(%monster);
		}
	}
	createTargetScanCastAnimation(%engineer);
	playAudio("Audio:consoleUse", EffectsAudioVolume.value);
	// Post-talent cleanup.
	scrollFloatingText(%engineer, "TARGET SCAN", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function magFist ()
{//echo("magFist()");
	%engineer = $playerSquad[$activeCharacter];
	if (%engineer.currentActionPoints < $magFistAPCost)
	{updateEventText($squadColor @ %engineer.name SPC $whiteColor @ "needs more AP to use Mag Fist" @ $defaultColor @ "!");
		return;
	}
	else
	{updateEventText($squadColor @ %engineer.name SPC $friendlyActionColor @ "uses Mag Fist" @ $defaultColor @ "!");
		%engineer.currentActionPoints -= $magFistAPCost;
	}
	// Perform Mag Fist.
	$squadMagFist = true;
	moveCharacter($activeCharacter, %grenadier.facing);	// This locks input via $currentCharacterActionFlag!
	//moveCharacter($activeCharacter, %engineer.facing);
	// Post-talent cleanup.
	scrollFloatingText(%engineer, "MAG FIST", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function weld ()
{//echo("weld()");
	%engineer = $playerSquad[$activeCharacter];
	if (%engineer.armor.armorRating < $weldARCost)
	{updateEventText($squadColor @ %engineer.name SPC $whiteColor @ "needs armor rating to use Weld" @ $defaultColor @ "!");
		return;
	}
	if (%engineer.currentHealth >= %engineer.maxHealth)
	{updateEventText($squadColor @ %engineer.name SPC $whiteColor @ "can't gain more any more health" @ $defaultColor @ "!");
		return;
	}
	if (%engineer.currentActionPoints < $weldAPCost)
	{updateEventText($squadColor @ %engineer.name SPC $whiteColor @ "needs more AP to use Weld" @ $defaultColor @ "!");
		return;
	}
	else
	{updateEventText($squadColor @ %engineer.name SPC $friendlyActionColor @ "uses Weld" @ $defaultColor @ "!");
		%engineer.currentActionPoints -= $weldAPCost;
	}
	// Perform Weld.
	%engineer.armor.armorRating -= $weldARCost;
	%engineer.armor.armorType = setWord(%engineer.armor.armorType, 2, %engineer.armor.armorRating);
	%engineer.currentHealth += $weldHealthGain;
	if (%engineer.currentHealth > %engineer.maxHealth)
	{
		%engineer.currentHealth = %engineer.maxHealth;
	}
	// Post-talent cleanup.
	scrollFloatingText(%engineer, "Weld", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}
function ammosmith ()
{//echo("ammosmith()");
	%engineer = $playerSquad[$activeCharacter];
	%grenadeSlot1 = -1;
	%grenadeSlot2 = -1;
	for (%i = 0; %i < $squadInventory.getCount(); %i++)
	{
		%item = $squadInventory.getObject(%i);
		if (%item.itemType == 10)	// Grenade.
		{
			if (%grenadeSlot1 == -1)
			{
				%grenadeSlot1 = %i;
			}
			else
			{
				%grenadeSlot2 = %i;
			}
		}
	}//echo(%grenadeSlot1 SPC %grenadeSlot2);
	if (%grenadeSlot1 == -1	||
		%grenadeSlot2 == -1)
	{updateEventText($squadColor @ %engineer.name SPC $whiteColor @ "needs grenades to use Ammosmith" @ $defaultColor @ "!");
		return;
	}
	if (%engineer.currentActionPoints < $ammosmithAPCost)
	{updateEventText($squadColor @ %engineer.name SPC $whiteColor @ "needs more AP to use Ammosmith" @ $defaultColor @ "!");
		return;
	}
	else
	{updateEventText($squadColor @ %engineer.name SPC $friendlyActionColor @ "uses Ammosmith" @ $defaultColor @ "!");
		%engineer.currentActionPoints -= $ammosmithAPCost;
	}
	// Perform Ammosmith.
	%grenade1 = $squadInventory.getObject(%grenadeSlot1);
	%grenade2 = $squadInventory.getObject(%grenadeSlot2);
	$squadInventory.remove(%grenade1);
	$squadInventory.remove(%grenade2);
	giveItem(1);		// Ammo Crate.
	// Post-talent cleanup.
	scrollFloatingText(%engineer, "AMMOSMITH", "talent");
	initializeReadout();
	autoSwitchSquadmember();
}