// Handles Unit Movement Control.
// Worthless Bums 2012.


function moveUnit (%unit, %xPos, %yPos, %linearSpeed, %autoStop, %callback, %snap, %targetMargin, %unitSwapping)
{//echo("moveUnit()" SPC %xPos SPC %yPos);
	if (%unit.name $= "Hulk"	&&
		!isSquadMember(%unit))
	{//echo("HULK SHIFT!");
		%yPos -= $TallUnitVerticalShift;
	}
	else if (%unit.name $= "Revenant"	&&
			 !isSquadMember(%unit))
	{//echo("REVENANT SHIFT!");
		%yPos -= $RevenantUnitVerticalShift;// - 1.8;		// HACK ALERT!
	}
	else if (%unit.name $= "Gunship"	&&
			 !isSquadMember(%unit))
	{//echo("GUSNHIP SHIFT!");
		%yPos -= $GunshipUnitVerticalShift;
	}
	if (isLargeUnit(%unit))
	{
		%yPos += $LargeUnitVerticalShift;
	}
	//usage: moveTo(worldPoint X/Y, speed, [autoStop = true], [warpToTarget = true])
	%unit.moveTo(%xPos SPC %yPos, %linearSpeed, %autoStop, false);	// Last param is "warpToTarget".
	// Weapon attachment should track with the unit!
	// HP and AP should track with the unit!
	if (isObject(%unit.laserSprite))
	{
		updateWeaponAttachmentPosition(%unit);
		for (%i = 1; %i <= 22; %i++)
		{
			schedule(%i * 10, 0, "updateWeaponAttachmentPosition", %unit);
			schedule(%i * 10, 0, "updateUnitHPAPPositions", %unit);
		}
	}
	else
	{
		for (%i = 1; %i <= 42; %i++)
		{
			schedule(%i * 10, 0, "updateUnitHPAPPositions", %unit);
		}
	}
	if (isSquadMember(%unit))
	{
		for (%i = 1; %i <= 22; %i++)
		{
			schedule(%i * 10, 0, "updateUnitIndicatorPosition", %unit);
			schedule(%i * 10, 0, "updateUnitPromotionIndicatorPosition", %unit);
		}
	}
	// Need to call this manually now!
	if (%callback)
	{
		schedule(200, 0, "checkMoveToStatus", %unit);	// HACK: ~200ms per complete move action!
	}
	// NOTE: Complete movement takes ~120 ms.
	%time = $growAndShrinkTime;
	%max = getWord(%unit.size, 1) * 2;		// Not a ratio - this is an absolute Torque internal unit max size parameter!
	growAndShrinkUnit(%unit, %max, %time);
}
function checkMoveToStatus (%unit)
{
	if (%unit.isMoveToComplete())
	{//echo("moveTo is complete!");
		onPositionTarget(%unit);
	}
	else
	{//echo("moveTo is NOT complete!");
		schedule(10, 0, "checkMoveToStatus", %unit);
	}
}
function inPlaceMonsterActionGrowAndShrink (%unit)
{//echo("inPlaceMonsterActionGrowAndShrink()");
	$fogOfWar.updateTargetMonsterVisibility(%unit);	// Update unit visibility!
	if (%unit.visible)	// Hidden monsters move too fast for this to work properly!
	{//echo("VISIBLE!");
		%time = $monsterStepDelay / 3;
		%max = getWord(%unit.size, 1) * 2;				// Not a ratio - this is an absolute Torque internal unit max size parameter!
		growAndShrinkUnit(%unit, %max, %time);
	}
}
function inPlaceActionGrowAndShrink (%unit)
{//echo("inPlaceActionGrowAndShrink()");
	$fogOfWar.updateTargetMonsterVisibility(%unit);	// Update unit visibility!
	if (%unit.visible)	// Hidden monsters move too fast for this to work properly!
	{//echo("VISIBLE!");
		%time = 120.0;
		if (isLargeUnit(%unit))
		{
			%max = getWord(%unit.size, 1) * 1.25;			// Not a ratio - this is an absolute Torque internal unit max size parameter!
		}
		else
		{
			%max = getWord(%unit.size, 1) * 2;				// Not a ratio - this is an absolute Torque internal unit max size parameter!
		}
		growAndShrinkUnit(%unit, %max, %time);
	}
}
// NOTE: This is used by function scrollFloatingText () for crits, et cetera!
function inPlaceActionGrowAndShrinkMax (%unit, %time, %max)
{//echo("inPlaceActionGrowAndShrinkMax()");l
	growAndShrinkUnit(%unit, %max, %time);
}
function hasSizeEventsPending ()
{//echo("hasSizeEventsPending()");
	return ($sizeEvents.getCount() > 0);
}
function cancelPendingSizeEvents ()
{//echo("cancelPendingSizeEvents()");
	if (!isObject($sizeEvents))
	{
		return;
	}
	for (%i = 0; %i < $sizeEvents.getCount(); %i++)
	{
		cancel($sizeEvents.getObject(%i));
	}
}
function trackShadow (%unit)
{//echo("trackShadow()");
	%xOffset = 0;
	%yOffset = 2;
	(%unit.shadow).position = (getWord(%unit.position, 0) + %xOffset) SPC (getWord(%unit.position, 1) + %yOffset);
}
// NOTE Parameter %max is not a ratio - this is an absolute Torque internal unit!
function shrinkAndGrowUnit (%unit, %max, %time)
{//echo("shrinkAndGrowUnit()");
	$fogOfWar.updateTargetMonsterVisibility(%unit);	// Update unit visibility!
	if (%unit.visible)	// Hidden monsters move too fast for this to work properly!
	{//echo("VISIBLE!");
		%unit.size = %unit.originalSize;
		$sizeEvents = new SimSet();
		//(%unit.shadow).dismount();
		%xOffset = 0;
		%yOffset = 1;
		%sizeX = getWord(%unit.size, 0);
		%sizeY = getWord(%unit.size, 1);
		%slices = 16;		// Make this an even number or the unit will permanently grow with each grow/shrink cycle!
		%timeMultiplier = %time / %slices;
		%sizePerSlice = (%max - %sizeX) / %slices;		// Could also use %sizeY for square sprites!
		%shadowTimer = 250;
		for (%i = 0; %i < %shadowTimer; %i += 10)
		{
			%shadowEvent = schedule(1 + %i, 0, "trackShadow", %unit);
		}
		for (%i = 0; %i < %slices; %i++)
		{
			if (%i < %slices / 2)
			{
				%sizeX -= %sizePerSlice;
				%sizeY -= %sizePerSlice;
			}
			else
			{
				%sizeX += %sizePerSlice;
				%sizeY += %sizePerSlice;
			}
			%sizeEvent = schedule(1 + %i * %timeMultiplier, 0, "changeUnitSize", %unit, %sizeX SPC %sizeY);
		}
		schedule(%shadowTimer + 10, 0, "mountShadowToUnit", %unit.shadow, %unit, %xOffset, %yOffset, 50.0);
	}
}
// NOTE Parameter %max is not a ratio - this is an absolute Torque internal unit!
function growAndShrinkUnit (%unit, %max, %time)
{//echo("growAndShrinkUnit()");
	$sizeEvents = new SimSet();
	//(%unit.shadow).dismount();
	%xOffset = 0;
	%yOffset = 1;
	%sizeX = getWord(%unit.size, 0);
	%sizeY = getWord(%unit.size, 1);
	%slices = 16;		// Make this an even number or the unit will permanently grow with each grow/shrink cycle!
	%timeMultiplier = %time / %slices;
	%sizePerSlice = (%max - %sizeX) / %slices;		// Could also use %sizeY for square sprites!
	%shadowTimer = 250;
	for (%i = 0; %i < %shadowTimer; %i += 10)
	{
		%shadowEvent = schedule(1 + %i, 0, "trackShadow", %unit);
	}
	for (%i = 0; %i < %slices; %i++)
	{
		if (%i < %slices / 2)
		{
			%sizeX += %sizePerSlice;
			%sizeY += %sizePerSlice;
		}
		else
		{
			%sizeX -= %sizePerSlice;
			%sizeY -= %sizePerSlice;
		}
		%sizeEvent = schedule(1 + %i * %timeMultiplier, 0, "changeUnitSize", %unit, %sizeX SPC %sizeY);
	}
	//schedule(%shadowTimer + 10, 0, "mountShadowToUnit", %unit.shadow, %unit, %xOffset, %yOffset, 50.0);
}
function changeUnitSize (%unit, %size)
{//echo("changeUnitSize()");
	%unit.size = %size;
}
function mountShadowToUnit (%shadow, %unit, %xOffset, %yOffset, %force)
{//echo("mountShadowToUnit()");
	if (isObject(%unit))
	{
		//%shadow.mount(%unit, %xOffset, %yOffset, %force, true, true, true, true);
	}
	else
	{
		if (isObject(%shadow))
		{
			%shadow.safeDelete();
		}
	}
}