public static void GenerateLevel(string StarsPath)
        {
            N8Level level = new N8Level();
            N8BlockFactory LevelBlocks = level.blocks;
            List<Vector3D> points = new List<Vector3D>();

            using (StreamReader sr = new StreamReader(File.OpenRead(StarsPath)))
            {
                string input;

                Regex SplitWhitespace = new Regex(@"\s+");
                while ((input = sr.ReadLine()) != null)
                {
                    string[] parts = SplitWhitespace.Split(input);
                    points.Add(new Vector3D(double.Parse(parts[3]), double.Parse(parts[4]), double.Parse(parts[5])));
                }
            }

            //Take only the first 300 stars
            points = points.Take(300).ToList();

            List<N8Block> stars;

            //Useful options:
            //snowmantop
            //letter.period
            //letter.period.big
            stars = Utilities.PlotPointsSphere(points, new Quaternion(0, 0, 0, 1), 1000, "snowmantop", "Star", level);

            N8Block ControlPoint = LevelBlocks.GenerateBlock("minipixelblack", "Control Point");

            foreach (N8Block star in stars)
            {
                ControlPoint.AttachToMe(star);
            }

            //Make a roof
            for (int i = -800; i <= 800; i += 400)
            {
                for (int j = -800; j <= 800; j += 400)
                {
                    N8Block roof = LevelBlocks.GenerateBlock("simplelandblack", "Vault of the Heavens");
                    roof.position = new Vector3D(i, j, 1000);
                }
            }

            string save = level.GenerateSaveFile();
            using(StreamWriter sw = new StreamWriter(File.Open(@"C:\Program Files (x86)\N8\Saves\planetarium.ncd", FileMode.Truncate)))
            {
                sw.WriteLine(save);
            }

            Console.WriteLine(save);
            Console.Read();
        }
        public static void Mirror()
        {
            string filename = @"C:\Program Files (x86)\N8\Saves\ctf_blu_wallsonly_wip.ncd";

            N8Level level = new N8Level(filename);

            List<N8Block> blue_blocks = (from b in level.blocks.Blocks where b.type.Contains("blue") select b).ToList<N8Block>();

            foreach (N8Block b in blue_blocks)
            {
                Console.WriteLine("Looking at " + b);
                N8Block red_clone = level.blocks.CloneBlock(b);
                Console.WriteLine("Clone is: " + red_clone);

                //necessary to change the type
                red_clone.type = red_clone.type.Replace("blue", "red");

                //Not necessary, cosmetic only.
                red_clone.name = red_clone.name.Replace("Blue", "Red");

                Console.WriteLine("Changed name, now it's: " + red_clone);

                red_clone.position = Utilities.ReflectPlane(red_clone.position, new Vector3D(1, 0, 0));

                Console.WriteLine("Reflected it, now it's: " + red_clone);
            }

            string result = level.GenerateSaveFile();
            Console.WriteLine(result);
            Console.Read();

            string outFilename = @"C:\Program Files (x86)\N8\Saves\out-test.ncd";

            using (StreamWriter sw = new StreamWriter(File.OpenWrite(outFilename)))
            {
                sw.Write(result);
            }
        }
        public static void GenerateLevel()
        {
            string SavePath = @"C:\Program Files (x86)\N8\Saves\maxprotecttest.ncd";
            string TronicsPath = @"C:\Program Files (x86)\N8\Saves\maxprotect_tronics_base_proxies.ncd";
            //I like black best, so make it more likely to show up
            //string[] colors = { "blue", "green", "orange", "purple", "red", "black", "black" };
            //Apparently nobody else likes the colors, so we're back to just black.
            string[] colors = { "black" };
            N8Level Level = new N8Level();
            N8Level tronics = new N8Level(TronicsPath);

            N8BlockFactory LevelBlocks = Level.blocks;

            Random rand = new Random();

            for (int i = -1000; i < 1380; i = i + 70)
            {
                for (int j = -1333; j <= 2000; j = j + 1333)
                {
                    for(int k = -1333; k <= 2000; k = k + 1333)
                    {
                        if (!(k == 0 && j == 0))
                        {
                            string color = colors[rand.Next(0, colors.Length)];
                            N8Block CurrentBlock = LevelBlocks.GenerateBlock("simpleland" + color, "Vault of the Heavens");
                            CurrentBlock.position.Z = i;
                            CurrentBlock.position.X = j;
                            CurrentBlock.position.Y = k;

                        }
                    }
                }
            }

            Level.MergeWithDestructive(tronics);

            //Non position dependent tronics - tronics whose position doesn't matter
            var NPDTronics = from N8Tronic t in LevelBlocks.Tronics
                                        where !(t.type == "rproximity" || t.type == "rkeyboard" || t.type == "tmover")
                                        select t;
            N8Block AttachmentPoint = (from N8Block b in LevelBlocks.Blocks
                                       where b.name == "Attach Point"
                                       select b).First();

            foreach (N8Tronic t in NPDTronics)
            {
                t.Detach();
                t.position.X = 0;
                t.position.Y = 0;
                t.position.Z = -250;
                AttachmentPoint.AttachToMe(t);
            }

            string ret = Level.GenerateSaveFile();
            Console.Read();

            if (!File.Exists(SavePath))
            {
                using (File.Create(SavePath)) { }
            }

            using (StreamWriter sw = new StreamWriter(File.Open(SavePath, FileMode.Truncate, FileAccess.Write, FileShare.None)))
            {
                sw.WriteLine(ret);
            }

            Console.WriteLine(ret);
        }
        public static void GenerateProxyMatrix()
        {
            string TronicsPath = @"C:\Program Files (x86)\N8\Saves\maxprotect_tronics_base.ncd";
            string SavePath = @"C:\Program Files (x86)\N8\Saves\maxprotect_tronics_base_proxies.ncd";

            N8Level tronics = new N8Level(TronicsPath);
            N8Level proxies = new N8Level();

            N8BlockFactory LevelBlocks = proxies.blocks;
            List<N8Tronic> ProxyBlocks = new List<N8Tronic>();

            int stepsize = 36;

            for (int i = -90 + stepsize; i <= 90 - stepsize; i += stepsize)
            {
                for (int j = -90 + stepsize; j <= 90 - stepsize; j += stepsize)
                {
                    N8Tronic LowerProxy = LevelBlocks.GenerateTronic("rproximity", "Detector Mesh");
                    LowerProxy.position.X = i;
                    LowerProxy.position.Y = j;
                    LowerProxy.position.Z = 45;

                    N8Tronic UpperProxy = LevelBlocks.GenerateTronic("rproximity", "Detector Mesh");
                    UpperProxy.position.X = i * 2.5;
                    UpperProxy.position.Y = j * 2.5;
                    UpperProxy.position.Z = 335;
                    UpperProxy.rotation = new Quaternion(new Vector3D(1, 0, 0), 90);

                    ProxyBlocks.Add(LowerProxy);
                    ProxyBlocks.Add(UpperProxy);
                }
            }

            proxies.MergeWithDestructive(tronics);

            N8Tronic MoverGateway = (from N8Tronic b in proxies.blocks.Tronics where b.type == "cifgreat" select b).First();

            N8Block ControlPoint = LevelBlocks.GenerateBlock("snowmancoal", "Control Point");
            ControlPoint.position.X = -100;

            foreach (N8Tronic prox in ProxyBlocks)
            {
                ControlPoint.AttachToMe(prox);
                //MoverGateway.WireTo(prox, Tronics.NodeType.FlowIn, Tronics.NodeType.FlowOutA);
            }

            Console.Read();
            if (!File.Exists(SavePath))
            {
                using (File.Create(SavePath)) { }
            }

            using (StreamWriter sw = new StreamWriter(File.Open(SavePath, FileMode.Truncate, FileAccess.Write, FileShare.None)))
            {
                sw.WriteLine(proxies.GenerateSaveFile());
            }
        }