// Handles line-of-sight.
// Worthless Bums 2012.


// Computes line-of-sight with Bresenham's line algorithm.
function bresenhamLineAlgorithm (%x0, %y0, %x1, %y1)
{//echo("bresenhamLineAlgorithm()");
	%dx = mAbs(%x1 - %x0);
	%dy = mAbs(%y1 - %y0);
	if (%x0 < %x1)
	{
		%sx = 1;
	}
	else
	{
		%sx = -1;
	}
	if (%y0 < %y1)
	{
		%sy = 1;
	}
	else
	{
		%sy = -1;
	}
	%err = %dx - %dy;
 
	while (true)
	{//echo("iter bre!");
		if (isObject($mazeRoom[%x0, %y0]))
		{//echo("$mazeRoom[%x0, %y0].status =" SPC $mazeRoom[%x0, %y0].status);
			if (//$mazeRoom[%x0, %y0].status == 0		||	// Not Walkable (not used anymore!).
				$mazeRoom[%x0, %y0].status == -1	||	// Water Tile.
				$mazeRoom[%x0, %y0].status == -2	||	// Wall.
				$mazeRoom[%x0, %y0].status == -3)		// Closed Door.
			{
				// Start tile is end tile.
				if (%x0 == %x1	&&
					%y0 == %y1)
				{//echo("END TILE IS OBSTACLE!-------------------------------------------------");
					// Uncover end tile if it is an obstacle!
					$fogOfWar.uncoverFogTile(%x0, %y0);
					
					// Target tile found - return success.
					return true;
				}
				else if (isObject($mazeRoom[%x0, %y0].porthole))
				{
					// Do nothing!
					// Allow line-of-sight to pass through portholes!
				}
				// Start tile is not end tile.
				else
				{
					// Hit an obstacle and target tile not reached - return failure.
					return false;
				}
			}
			else
			{
				// Check if there is an obscuring effect on this tile.
				if (hasObscuringEffect(%x0, %y0))
				{
					// NOTE: this code should only run if there is clear los between this tile and the specified initial tile!
					$fogOfWar.uncoverFogTile(%x0, %y0);
					
					return false;
				}
			}
		}
		
		if (%x0 == %x1	&&
			%y0 == %y1)
		{
			return true;
		}
		
		%e2 = 2 * %err;
		
		if (%e2 > -1 * %dy)
		{
			%err = %err - %dy;
			%x0 = %x0 + %sx;
		}
		if (%e2 < %dx)
		{
			%err = %err + %dx;
			%y0 = %y0 + %sy;
		}
	}
	
	return true;
}
function targetsInLineOfSight (%srcX, %srcY, %tgtX, %tgtY)//echo(targetsInLineOfSight(22, 18, 22, -11));
{//echo("targetsInLineOfSight()");
//echo(%srcX SPC %srcY SPC %tgtX SPC %tgtY);
	if (%srcX == %tgtX	&&
		%srcy == %tgtY)
	{
		return true;	// Source and target on the same tile!
	}
	if (%srcX == %tgtX)
	{//echo("VERTICAL");
		%startY = %srcY;
		%endY = %tgtY;
		if (%tgtY < %srcY)
		{
			%startY = %tgtY;
			%endY = %srcY;
		}
		for (%i = %startY; %i < $mazeDimension - 1; %i++)
		{//echo(%srcX SPC %i);
			if (!canFireThrough(%srcX, %i))
			{//echo("obstacle at " @ %srcX SPC %i);
				return false;
			}
			if (%i == %endY)
			{//echo("matched!" SPC %srcX SPC %srcX);
				return true;
			}
		}
	}
	else if (%srcY == %tgtY)
	{//echo("HORIZONTAL");
		%startX = %srcX;
		%endX = %tgtX;
		if (%tgtX < %srcX)
		{
			%startX = %tgtX;
			%endX = %srcX;
		}
		for (%i = %startX; %i < $mazeDimension - 1; %i++)
		{//echo(%i SPC %srcY);
			if (!canFireThrough(%i, %srcY))
			{//echo("obstacle at " @ %i SPC %srcY);
				return false;
			}
			if (%i == %endX)
			{//echo("matched!" SPC %i SPC %srcY);
				return true;
			}
		}
	}
	else
	{//echo("target not in line of sight!");
		return false;
	}
//echo("TARGET IN LINE OF SIGHT!");
	return true;
}