// Handles Active Character Powers.
// Worthless Bums 2012.


function resetSquadPowerCooldowns ()
{//echo("resetSquadPowerCooldowns()");
	// Bash.
	$squadPowerBashOnCooldown = false;
	$squadPowerBashCooldownTurns = 0;
	if (isObject(squadPowerBashCooldown))
	{
		exploreGui.remove(squadPowerBashCooldown);
	}
	// Radar.
	$squadPowerRadarOnCooldown = false;
	$squadPowerRadarCooldownTurns = 0;
	if (isObject(squadPowerRadarCooldown))
	{
		exploreGui.remove(squadPowerRadarCooldown);
	}
	// Shield.
	$squadPowerShieldOnCooldown = false;
	$squadPowerShieldCooldownTurns = 0;
	if (isObject(squadPowerShieldCooldown))
	{
		exploreGui.remove(squadPowerShieldCooldown);
	}
}
function updateSquadPowerCooldowns ()
{//echo("updateSquadPowerCooldowns()");
	if ($squadPowerBashOnCooldown)
	{
		$squadPowerBashCooldownTurns--;
		
		if ($squadPowerBashCooldownTurns <= 0)
		{
			$squadPowerBashCooldownTurns = 0;
			$squadPowerBashOnCooldown = false;
			exploreGui.remove(squadPowerBashCooldown);
		}
		else
		{//echo("changing bitmap!");
			squadPowerBashCooldown.bitmap = "../../../Sprites/1/assets/images/UI/cooldownOverlay" @ $squadPowerBashCooldownTurns;
			squadPowerBashCooldown.ToolTip = "Bash: " @ $squadPowerBashCooldownTurns @ " turns on cooldown.";
		}
	}
	// Handle squad power radar cooldown.
	if ($squadPowerRadarOnCooldown)
	{
		$squadPowerRadarCooldownTurns--;
		if ($squadPowerRadarCooldownTurns <= 0)
		{
			$squadPowerRadarCooldownTurns = 0;
			$squadPowerRadarOnCooldown = false;
			exploreGui.remove(squadPowerRadarCooldown);
		}
		else
		{//echo("changing bitmap!");
			squadPowerRadarCooldown.bitmap = "../../../Sprites/1/assets/images/UI/cooldownOverlay" @ $squadPowerRadarCooldownTurns;
			squadPowerRadarCooldown.ToolTip = "Radar: " @ $squadPowerRadarCooldownTurns @ " turns on cooldown.";
		}
	}
	// Handle squad power shield cooldown.
	if ($squadPowerShieldOnCooldown)
	{
		$squadPowerShieldCooldownTurns--;
		if ($squadPowerShieldCooldownTurns <= 0)
		{
			$squadPowerShieldCooldownTurns = 0;
			$squadPowerShieldOnCooldown = false;
			exploreGui.remove(squadPowerShieldCooldown);
		}
		else
		{//echo("changing bitmap!");
			squadPowerShieldCooldown.bitmap = "../../../Sprites/1/assets/images/UI/cooldownOverlay" @ $squadPowerShieldCooldownTurns;
			squadPowerShieldCooldown.ToolTip = "Shield: " @ $squadPowerShieldCooldownTurns @ " turns on cooldown.";
		}
	}
}
function useSquadPowerBash ()
{//echo("useSquadPowerBash()");
	if ($squadPowerBashOnCooldown)
	{
		return;
	}
	else
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Squad Power Bash" @ $defaultColor @ "!");
	}
	createSquadPowerBashAnimation();
	initSquadPowerBashCooldown();
	%range = 8.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);
}
function initSquadPowerBashCooldown ()
{//echo("initSquadPowerBashCooldown()");
	$squadPowerBashOnCooldown = true;
	$squadPowerBashCooldownTurns = 10;
	new GuiBitmapButtonCtrl(squadPowerBashCooldown)
	{
		canSaveDynamicFields = "0";
		isContainer = "0";
		Profile = "GuiDefaultProfile";
		HorizSizing = "relative";
		VertSizing = "relative";
		Position = squadPowerBashButton.position;
		Extent = squadPowerBashButton.extent;//"32 32";
		MinExtent = "8 2";
		canSave = "1";
		Visible = "1";
		hovertime = "0";
		groupNum = "-1";
		buttonType = "PushButton";
		useMouseEvents = "1";
		tooltipprofile = "SquadPowerProfile";
		ToolTip = "Bash: " @ $squadPowerBashCooldownTurns @ " turns on cooldown.";
		Command = "useSquadPowerBash();";
		bitmap = "../../../Sprites/1/assets/images/UI/cooldownOverlay10";
	};
	exploreGui.add(squadPowerBashCooldown);
}
function useRadar ()
{//echo("useRadar()");
	createSquadPowerRadarAnimation();
	%range = 20.0;		// Kind of arbitrary.
	for (%i = 0; %i < $monsterList.getCount(); %i++)
	{
		%monster = $monsterList.getObject(%i);
		%distance = VectorDist(%monster.getPosition(), $playerSquad[$activeCharacter].getPosition());
		if (%distance <= %range)
		{
			$fogOfWar.uncoverFogTile(%monster.xIndex, %monster.yIndex);
		}
	}
	playAudio("Audio:squadPowerRadar", EffectsAudioVolume.value);
	$fogOfWar.schedule(250, "showAndTellMonsters");
}
function useSquadPowerRadar ()
{//echo("useSquadPowerRadar()");
	if ($squadPowerRadarOnCooldown)
	{
		return;
	}
	else
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Squad Power Radar" @ $defaultColor @ "!");
	}
	createSquadPowerRadarAnimation();
	initSquadPowerRadarCooldown();
	%range = 20.0;		// Kind of arbitrary.
	for (%i = 0; %i < $monsterList.getCount(); %i++)
	{
		%monster = $monsterList.getObject(%i);
		%distance = VectorDist(%monster.getPosition(), $playerSquad[$activeCharacter].getPosition());
		if (%distance <= %range)
		{
			$fogOfWar.uncoverFogTile(%monster.xIndex, %monster.yIndex);
		}
	}
	playAudio("Audio:squadPowerRadar", EffectsAudioVolume.value);
}
function initSquadPowerRadarCooldown ()
{//echo("initSquadPowerRadarCooldown()");
	$squadPowerRadarOnCooldown = true;
	$squadPowerRadarCooldownTurns = 8;
	new GuiBitmapButtonCtrl(squadPowerRadarCooldown)
	{
		canSaveDynamicFields = "0";
		isContainer = "0";
		Profile = "GuiDefaultProfile";
		HorizSizing = "relative";
		VertSizing = "relative";
		Position = squadPowerRadarButton.position;
		Extent = squadPowerRadarButton.extent;//"32 32";
		MinExtent = "8 2";
		canSave = "1";
		Visible = "1";
		hovertime = "0";
		groupNum = "-1";
		buttonType = "PushButton";
		useMouseEvents = "1";
		tooltipprofile = "SquadPowerProfile";
		ToolTip = "Radar: " @ $squadPowerRadarCooldownTurns @ " turns on cooldown.";
		Command = "useSquadPowerRadar();";
		bitmap = "../../../Sprites/1/assets/images/UI/cooldownOverlay8";
	};
	exploreGui.add(squadPowerRadarCooldown);
}
function useSquadPowerShield ()
{//echo("useSquadPowerShield()");
	if ($squadPowerShieldOnCooldown)
	{
		return;
	}
	else
	{
		updateEventText($squadColor @ $playerSquad[$activeCharacter].name SPC $friendlyActionColor @ "uses Squad Power Shield" @ $defaultColor @ "!");
	}
	createSquadPowerShieldAnimation();
	initSquadPowerShieldCooldown();
	playAudio("Audio:squadPowerShield", EffectsAudioVolume.value);
}
function initSquadPowerShieldCooldown ()
{//echo("initSquadPowerShieldCooldown()");
	$squadPowerShieldOnCooldown = true;
	$squadPowerShieldCooldownTurns = 10;
	new GuiBitmapButtonCtrl(squadPowerShieldCooldown)
	{
		canSaveDynamicFields = "0";
		isContainer = "0";
		Profile = "GuiDefaultProfile";
		HorizSizing = "relative";
		VertSizing = "relative";
		Position = squadPowerShieldButton.position;
		Extent = squadPowerShieldButton.extent;//"32 32";
		MinExtent = "8 2";
		canSave = "1";
		Visible = "1";
		hovertime = "0";
		groupNum = "-1";
		buttonType = "PushButton";
		useMouseEvents = "1";
		tooltipprofile = "SquadPowerProfile";
		ToolTip = "Radar: " @ $squadPowerShieldCooldownTurns @ " turns on cooldown.";
		Command = "useSquadPowerShield();";
		bitmap = "../../../Sprites/1/assets/images/UI/cooldownOverlay10";
	};
	exploreGui.add(squadPowerShieldCooldown);
	$characterWithShield = $activeCharacter;
	($playerSquad[$activeCharacter].armor).armorRating *= 2;
	updateSquadInfoGui();
}
function characterBashMonster (%monsterIndex)
{//echo("characterBashMonster()");
	%monster = $monsterList.getObject(%monsterIndex);
	%characterAttackModifier = ($playerSquad[$activeCharacter].weapon).accuracy - %monster.evasion;
	%attackRoll = getRandom(1, 100);
	if (%attackRoll <= %characterAttackModifier)
	{
		%damage = ($playerSquad[$activeCharacter].weapon).damage - %monster.armorRating;
		if (%damage < 0)
		{
			%damage = 0;
		}
		scrollFloatingText(%monster, %damage, "damage");
		if (%damage >= %monster.currentHealth)
		{
			if (%monster.isRobot)
			{
				triggerArmorRepair();
			}
			%monster.currentHealth = 0;
			updateKillRecord($activeCharacter, %monster.name, %monster.level);
			handleMonsterDeath($activeCharacter, %monsterIndex);
			updateEventText($monsterColor @ %monster.name SPC $damageColor @ "killed by" SPC $friendlyActionColor @ "Squad Bash" @ $defaultColor @ "!");
			return;
		}
		else
		{
			%monster.currentHealth -= %damage;
		}
		handleBloodSplatter(%monster.xIndex, %monster.yIndex);
		// Calculate tile just after targeted monster.
		%xPos = getWord($playerSquad[$activeCharacter].getPosition(), 0);
		%yPos = getWord($playerSquad[$activeCharacter].getPosition(), 1);
		%mxPos = getWord(%monster.getPosition(), 0);
		%myPos = getWord(%monster.getPosition(), 1);
		%xDiff = 4;
		%yDiff = 4;
		// Monster bashed left.
		if (%yPos == %myPos)
		{
			%yDiff = 0;
			if (%xPos > %mxPos)
			{
				%xDiff = -4;
			}
		}
		// Monster bashed up.
		else if (%xPos == %mxPos)
		{
			%xDiff = 0;
			if (%yPos > %myPos)
			{
				%yDiff = -4;
			}
		}
		// Calculate indices to move to.
		%indices = getIndicesFromTilePosition(%mxPos + %xDiff, %myPos + %yDiff);
		%xIndex = getWord(%indices, 0);
		%yIndex = getWord(%indices, 1);
		// Bounds check indices.
		if (%xIndex >= 0				&&
			%xIndex < $mazeDimension	&&
			%yIndex >= 0				&&
			%yIndex < $mazeDimension)
		{
			if (tileIsClear(%xIndex, %yIndex))
			{//echo("tile is clear!");
				// Handle knockback of character.
				%monster.moveTo(%mxPos + %xDiff, %myPos + %yDiff, 60.0, true, false);
				playRandomFootstepSfx();
				%monster.xIndex = %xIndex;
				%monster.yIndex = %yIndex;
			}
			// Check if monster was knocked into outer space!
			else if (tileIsOpenSpace(%xIndex, %yIndex))
			{//echo("knocking monster into space!");
				$GlobalStats.totalEnemiesKnockedIntoSpace++;
				$GlobalStats.totalKills++;
				// Handle knockback of character.
				%monster.moveTo(%mxPos + %xDiff, %myPos + %yDiff, 60.0, true, false);
				playRandomFootstepSfx();
				%monster.xIndex = %xIndex;
				%monster.yIndex = %yIndex;
				handleSpecialMonsterDeath(%monster);
				%monster.schedule($spaceKnockOutDelay, "safeDelete");
				schedule($spaceKnockOutDelay, 0, "updateEventText", $monsterColor @ %monster.name @ $hostileActionColor @ " shrieks as it's knocked out into space" @ $defaultColor @ "!");
				schedule($spaceKnockOutDelay, 0, "updateCharacterExperience", $activeCharacter, %monster.name, %monster.level);
			}
		}
		updateEventText($monsterColor @ %monster.name SPC $friendlyActionColor @ "hit by Squad Bash for" SPC $damageColor @ %damage @ " damage" @ $defaultColor @ "!");
	}
	// Attack missed, update the event log.
	else
	{
		updateEventText($monsterColor @ %monster.name SPC $hostileActionColor @ "evades" SPC $friendlyActionColor @ "Squad Bash" @ $defaultColor @ "!");
	}
	// Wake the monster.
	monsterAttackedReaction(%monster);
}
// Returns the direction between the two specified points.
// NOTE: This function assumes at least one direction of cardinal alignment - not the responsibility of this function to ensure!
function getDirectionBetweenPoints (%xIndex1, %yIndex1, %xIndex2, %yIndex2)
{//echo("getDirectionBetweenPoints()");
	if (%yIndex1 > %yIndex2)
	{
		return $northDirection;
	}
	if (%yIndex1 < %yIndex2)
	{
		return $southDirection;
	}
	if (%xIndex1 < %xIndex2)
	{
		return $eastDirection;
	}
	if (%xIndex1 > %xIndex2)
	{
		return $westDirection;
	}
}
// Returns the direction between the source and destination object.
// NOTE: This function assumes at least one direction of cardinal alignment - not the responsibility of this function to ensure!
function getDirectionBetweenUnits (%srcUnit, %dstUnit)
{//echo("getDirectionBetweenUnits()");
	if (%srcUnit.yIndex > %dstUnit.yIndex)
	{
		return $northDirection;
	}
	if (%srcUnit.yIndex < %dstUnit.yIndex)
	{
		return $southDirection;
	}
	if (%srcUnit.xIndex < %dstUnit.xIndex)
	{
		return $eastDirection;
	}
	if (%srcUnit.xIndex > %dstUnit.xIndex)
	{
		return $westDirection;
	}
}
function setEnemyKnockBack (%knockBack)
{
	$EnemyKnockBack = %knockBack;
}
// Calculates generic knock back effect.
function knockBackUnit (%unit, %direction)
{//echo("knockBackUnit()");
	%unit.xIndex = mRound(%unit.xIndex);
	%unit.yIndex = mRound(%unit.yIndex);
	//triggerSlowdownKnockBackEffect();
	knockBackCameraShake();
	// Calculate indices to move to.
	%xIndex = %unit.xIndex;
	%yIndex = %unit.yIndex;
	switch (%direction)
	{
		case $northDirection:	%yIndex--;
		case $eastDirection:	%xIndex++;
		case $southDirection:	%yIndex++;
		case $westDirection:	%xIndex--;
	}
	%position = getTilePositionFromIndices(%xIndex, %yIndex);	// Why is this calculating an incorrect tile position?
	if (%xIndex >= 0				&&
		%xIndex < $mazeDimension	&&
		%yIndex >= 0				&&
		%yIndex < $mazeDimension)
	{//echo("checking tile!");
		// Make sure the tile is clear.
		if (canFireThrough(%xIndex, %yIndex)	&&
			!isObject($mazeRoom[%xIndex, %yIndex].porthole))
		{
			if (tileIsClearOfUnits(%xIndex, %yIndex))
			{
				// The Patriarch can't be instagibbed by being knocked into space!
				if (%unit.name $= "Patriarch"	&&
					!isSquadMember(%unit)		&&	// Not a marine named "Patriarch"!
					tileIsOpenSpace(%xIndex, %yIndex))
				{
					// Patriarch is not happy!
					setIndividualDialoguePopup(%unit, "&##sdfs$#&df$%@!", "dialogue");
					return;
				}
				else
				{
					// Flag so impulse will not occur!
					//setEnemyKnockBack(true);
					//schedule(50, 0, "setEnemyKnockBack", false);
					// Handle knockback of unit.
					%unit.xIndex = %xIndex;
					%unit.yIndex = %yIndex;
					//moveUnit(%unit, getWord(%position, 0), getWord(%position, 1) + $GlobalVerticalShift, 60.0, true, false, false, 0.0, false);
					moveUnit(%unit, getWord(%position, 0), getWord(%position, 1), 60.0, true, false, false, 0.0, false);
				}
			}
		}
		// Check if unit was knocked into outer space!
		if (tileIsOpenSpace(%xIndex, %yIndex))
		{//echo("tile is open space!");
			// Check if this unit is a monster!
			if (isMonster(%unit))
			{
				triggerKnockEnemyOutOfShip();
				// Increment total Enemies Knocked Into Space!
				$GlobalStats.totalEnemiesKnockedIntoSpace++;
			}
			// Check for special monster death triggers.
			%returnObject = handleSpecialMonsterDeath(%unit);
			if (isObject(%returnObject))
			{
				%returnObject.safeDelete();
			}
			// Schedule unit delete.
			if (isMonster(%unit))
			{
				(%unit.floatingHPText).safeDelete();
				(%unit.floatingAPText).safeDelete();
				%unit.schedule($spaceKnockOutDelay, "safeDelete");
				schedule($spaceKnockOutDelay, 0, "updateEventText", $monsterColor @ %unit.name @ $hostileActionColor @ " is knocked out into space" @ $defaultColor @ "!");
				$enemiesKnockedIntoSpace++;
				$GlobalStats.totalKills++;
				updateMissionObjectives();
			}
			else
			{
				%characterIndex = -1;
				for (%i = 0; %i < 4; %i++)
				{
					if (%unit == $playerSquad[%i])
					{
						%characterIndex = %i;
					}
				}
				if (%characterIndex != -1)
				{
					executeSquadMemberDeath(%characterIndex, false, "[Space]");
					updateMissionObjectives();
				}
			}
		}
	}
	// Trigger traps if the unit is on any.
	characterOnTrap(%unit);
	//$enemyImpulse = true;
	//schedule(100, 0, "enforceMonsterIndices");
	schedule(100, 0, "handleLiftedTileMarker", %unit);
}