WorldStudio.cs
namespace PixelPusher;

public static class WorldStudio
{
	public const float SlabDepth = 18f;

	public static int Zoom = 1;
	public static float CamX;
	public static float CamY;
	public static void SetZoom( int zoom )
	{
		Zoom = Math.Clamp( zoom, 1, 4 );
		GameFlow.Bump();
	}

	public static void EnsureFramed()
	{
		if ( MathF.Abs( CamX ) > 1f || MathF.Abs( CamY ) > 1f )
			return;
		var stage = Desk.Stage;
		var start = stage?.Find( "start" );
		if ( start is null || stage is null )
			return;
		CamX = start.Tx * stage.TileSize + SlabDepth * 0.55f - 160f;
		CamY = start.Ty * stage.TileSize - SlabDepth * 0.28f - 90f;
		ClampCam();
	}

	public static void FocusPlayer( float px, float py, float pz )
	{
		CamX = px + pz * 0.55f - 160f;
		CamY = py - pz * 0.28f - 90f;
		ClampCam();
	}

	public static void Pan( float dx, float dy )
	{
		CamX += dx;
		CamY += dy;
		ClampCam();
	}

	public static void TickCamera()
	{
		if ( GameFlow.Screen != GameScreen.World )
			return;

		var speed = 280f * Time.Delta;
		if ( Input.Down( "Run" ) )
			speed *= 2.2f;
		if ( Input.Down( "Left" ) ) CamX -= speed;
		if ( Input.Down( "Right" ) ) CamX += speed;
		if ( Input.Down( "Forward" ) ) CamY -= speed;
		if ( Input.Down( "Backward" ) ) CamY += speed;
		ClampCam();
	}

	public static void Project( float x, float y, float z, out int sx, out int sy, float scale, float camX, float camY )
	{
		sx = (int)MathF.Round( (x + z * 0.55f - camX) * scale );
		sy = (int)MathF.Round( (y - z * 0.28f - camY) * scale );
	}

	static void ClampCam()
	{
		var stage = Desk.Stage;
		if ( stage is null )
			return;
		var worldW = stage.Width * stage.TileSize + SlabDepth;
		var worldH = stage.Height * stage.TileSize;
		CamX = Math.Clamp( CamX, -40, Math.Max( -40, worldW - 280 ) );
		CamY = Math.Clamp( CamY, -40, Math.Max( -40, worldH - 140 ) );
	}
}