// Charge Handler.
// Worthless Bums 2012.


// Returns true iff the specified indices has a barrel.
function tileHasBarrel (%xIndex, %yIndex)
{
	for (%i = 0; %i < $barrelList.getCount(); %i++)
	{
		%barrel = $barrelList.getObject(%i);
		if (%barrel.xIndex == %xIndex	&&
			%barrel.yIndex == %yIndex)
		{
			return true;
		}
	}
	return false;
}
// Charge unit in a direction.
function chargeInDirection (%unit, %direction, %range, %chargeDamage)
{//echo("chargeInDirection()");
	if (%range <= 0)
	{
		return;
	}
	%xIndex = %unit.xIndex;
	%yIndex = %unit.yIndex;
	%xBuffer = 0;
	%yBuffer = 0;
	%tilePosition = "-9999 -9999";
	for (%i = 1; %i <= %range; %i++)
	{
		switch (%direction)
		{
			case $northDirection:	%yBuffer--;
			case $southDirection:	%yBuffer++;
			case $eastDirection:	%xBuffer++;
			case $westDirection:	%xBuffer--;
		}
		if (canFireThrough(%xIndex + %xBuffer, %yIndex + %yBuffer))
		{
			%tileUnit = tileHasUnit(%xIndex + %xBuffer, %yIndex + %yBuffer);
			if (isObject(%tileUnit)											||
				tileHasDispenser(%xIndex + %xBuffer, %yIndex + %yBuffer)	||
				tileHasCryoTube(%xIndex + %xBuffer, %yIndex + %yBuffer)		||
				tileHasBarrel(%xIndex + %xBuffer, %yIndex + %yBuffer)		||
				isSpaceTile(%xIndex + %xBuffer, %yIndex + %yBuffer))
			{
				switch (%direction)
				{
					case $northDirection:
						%tilePosition = getTilePositionFromIndices(%xIndex + %xBuffer, %yIndex + %yBuffer + 1);
						%unit.xIndex = %xIndex + %xBuffer;
						%unit.yIndex = %yIndex + %yBuffer + 1;
					case $southDirection:
						%tilePosition = getTilePositionFromIndices(%xIndex + %xBuffer, %yIndex + %yBuffer - 1);
						%unit.xIndex = %xIndex + %xBuffer;
						%unit.yIndex = %yIndex + %yBuffer - 1;
					case $eastDirection:
						%tilePosition = getTilePositionFromIndices(%xIndex + %xBuffer - 1, %yIndex + %yBuffer);
						%unit.xIndex = %xIndex + %xBuffer - 1;
						%unit.yIndex = %yIndex + %yBuffer;
					case $westDirection:
						%tilePosition = getTilePositionFromIndices(%xIndex + %xBuffer + 1, %yIndex + %yBuffer);
						%unit.xIndex = %xIndex + %xBuffer + 1;
						%unit.yIndex = %yIndex + %yBuffer;
				}
				%unit.moveTo(getWord(%tilePosition, 0), getWord(%tilePosition, 1), 60.0, true, false);
				if (isObject(%tileUnit))
				{
					schedule($knockBackDelay, 0, "knockBackUnit", %tileUnit, %direction);	// Shifted upward incorrectly!
					if (%chargeDamage > 0)
					{
						%characterIndex = -1;
						if ($leaderPersist	&&	%tileUnit == $playerSquad[0])
						{
							%characterIndex = 0;
						}
						else if ($scoutPersist	&&	%tileUnit == $playerSquad[1])
						{
							%characterIndex = 1;
						}
						else if ($grenadierPersist	&&	%tileUnit == $playerSquad[2])
						{
							%characterIndex = 2;
						}
						else if ($supportPersist	&&	%tileUnit == $playerSquad[3])
						{
							%characterIndex = 3;
						}
						%damage = applyPassiveTalentDamageReduction(%characterIndex, %chargeDamage, "physical");
						characterHit(%characterIndex, %damage, %unit, %unit.rangeDamageType, "normal");
						scrollFloatingText($playerSquad[%characterIndex], %damage, %unit.rangeDamageType, "normal");
						if (%tileUnit.currentHealth <= %damage)
						{
							%tileUnit.currentHealth = 0;
							$GlobalStats.totalDamageTaken += %damage;
							executeSquadMemberDeath(%characterIndex, true, %unit.name);
						}
						else
						{
							%tileUnit.currentHealth -= %damage;
						}
						updateFloatingHealthPointText(%characterIndex);
					}
				}
				checkUnitOnSpaceTile(%unit);
				return;
			}
		}
		else
		{
			switch (%direction)
			{
				case $northDirection:	%tilePosition = getTilePositionFromIndices(%xIndex + %xBuffer, %yIndex + %yBuffer + 1);
				case $southDirection:	%tilePosition = getTilePositionFromIndices(%xIndex + %xBuffer, %yIndex + %yBuffer - 1);
				case $eastDirection:	%tilePosition = getTilePositionFromIndices(%xIndex + %xBuffer - 1, %yIndex + %yBuffer);
				case $westDirection:	%tilePosition = getTilePositionFromIndices(%xIndex + %xBuffer + 1, %yIndex + %yBuffer);
			}
			%unit.moveTo(getWord(%tilePosition, 0), getWord(%tilePosition, 1), 60.0, true, false);
			return;
		}
	}
	// Max range Charge - no obstacles!
	%tilePosition = getTilePositionFromIndices(%xIndex + %xBuffer, %yIndex + %yBuffer);
	%unit.xIndex = %xIndex + %xBuffer;
	%unit.yIndex = %yIndex + %yBuffer;
	%unit.moveTo(getWord(%tilePosition, 0), getWord(%tilePosition, 1), 60.0, true, false);
	checkUnitOnSpaceTile(%unit);
}
function checkUnitOnSpaceTile (%unit)
{//echo("checkUnitOnSpaceTile()");
	if (tileIsOpenSpace(%unit.xIndex, %unit.yIndex))
	{//echo("knocked into space!");
		if (isSquadMember(%unit))
		{
			%characterIndex = -1;
			if ($leaderPersist	&&	%unit == $playerSquad[0])
			{
				%characterIndex = 0;
			}
			else if ($scoutPersist	&&	%unit == $playerSquad[1])
			{
				%characterIndex = 1;
			}
			else if ($grenadierPersist	&&	%unit == $playerSquad[2])
			{
				%characterIndex = 2;
			}
			else if ($supportPersist	&&	%unit == $playerSquad[3])
			{
				%characterIndex = 3;
			}
			if (%characterIndex != -1)
			{
				//updateMissionObjectives();	// Missions disabled for now!
				schedule($spaceKnockOutDelay, 0, "setKnockedIntoSpaceDialogue", %unit);
				schedule($spaceKnockOutDelay, 0, "executeSquadMemberDeath", %characterIndex, false, "[Space]");
				schedule($spaceKnockOutDelay, 0, "updateMissionObjectives");
			}
		}
		else
		{
			handleSpecialMonsterDeath(%unit);
			%unit.schedule($spaceKnockOutDelay, "safeDelete");
		}
	}
}