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 void MergeWithSafe(N8Level other) { this.blocks.CopyFromNonDestructive(other.blocks); }
public static void GenerateProxyBimesh() { string SavePath = @"C:\Program Files (x86)\N8\Saves\proxybimesh.ncd"; N8Level Level = new N8Level(); N8BlockFactory LevelBlocks = Level.blocks; List<FlowTronic> proxies = new List<FlowTronic>(); for (int i = -330; i <= 330; i += 60) { for (int j = -330; j <= 330; j += 60) { int x = i; int y = j; if ((i/60) % 2 == 0) { y = j + 15; } else { y = j - 15; } if ((j / 60) % 2 == 0) { x = i + 15; } else { x = i - 15; } Vector3D pos = new Vector3D(x, y, 1000); FlowTronic TopProxy = LevelBlocks.Proxy(x + "," + y); pos.Z = 270; TopProxy.position = pos; FlowTronic BottomProxy = LevelBlocks.Proxy(x + "," + y); pos.Z = 0; BottomProxy.position = pos; proxies.Add(TopProxy); proxies.Add(BottomProxy); } } FleeTronics(LevelBlocks, proxies); Utilities.Save(SavePath, Level); }
public static N8Level GetProxyBubble() { N8Level Level = new N8Level(); Quaternion UpsideDown = new Quaternion(new Vector3D(1, 0, 0), 180); N8BlockFactory LevelBlocks = Level.blocks; List<Tuple<Vector3D, Quaternion>> proxies = new List<Tuple<Vector3D,Quaternion>>(); //points.AddRange(Utilities.EvenCircle(new Vector3D(0, 0, -1), 45, 45)); //points.AddRange(Utilities.EvenCircle(new Vector3D(0, 0, 250), 45, 45)); proxies.Add(Tuple.Create(new Vector3D(120, 0, 250), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(-120, 0, 250), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(0, 120, 250), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(0, -120, 250), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(50, 50, 50), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(-50, 50, 50), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(50, -50, 50), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(-50, -50, 50), new Quaternion())); proxies.AddRange(Utilities.EvenSphere(new Vector3D(0, 0, 50), 85, 480, (double)8 / 16 * Math.PI)); //points.AddRange(Utilities.EvenSphere(new Vector3D(0, 0, 50), 85, 175, (double)8 / 16 * Math.PI)); proxies.AddRange(Utilities.EvenCircle(new Vector3D(0, 0, 0), 90, 300)); proxies.AddRange(Utilities.EvenCircle(new Vector3D(0, 0, 0), 80, 250)); proxies.AddRange(Utilities.EvenCircle(new Vector3D(0, 0, 0), 70, 200)); proxies.AddRange(Utilities.EvenCircle(new Vector3D(0, 0, 0), 60, 150)); proxies.AddRange(Utilities.EvenCircle(new Vector3D(0, 0, 0), 50, 75)); proxies.AddRange(Utilities.EvenCircle(new Vector3D(0, 0, 0), 45, 20)); //points.AddRange(Utilities.EvenCircle(new Vector3D(0, 0, 50), 90, 700)); //*/ List<Tuple<Vector3D, Quaternion>> targets = new List<Tuple<Vector3D, Quaternion>>(); targets.AddRange(Utilities.EvenSphere(new Vector3D(0, 0, 50), 45, 50, (double)10 / 16 * Math.PI)); Quaternion ProxyRot = new Quaternion(new Vector3D(0, 0, 1), -90) * new Quaternion(new Vector3D(0,1,0), 90); Quaternion TargetRot = new Quaternion();//new Vector3D(0, 1, 0), -90); List<FlowTronic> alerts = new List<FlowTronic>(); for(int i = 0; i < proxies.Count; i++) { Tuple<Vector3D, Quaternion> t = proxies[i]; FlowTronic prox = LevelBlocks.Proxy("i=" + i); prox.position = t.Item1; alerts.Add(prox); } for (int i = 0; i < targets.Count; i++) { Tuple<Vector3D, Quaternion> t = targets[i]; FlowTronic target = LevelBlocks.Target("i=" + i); target.position = t.Item1; target.rotation = TargetRot * t.Item2; alerts.Add(target); } FleeTronics(LevelBlocks, alerts); //Console.WriteLine("Total number of blocks used: " + (LevelBlocks.Tronics.Count + LevelBlocks.Blocks.Count)); return Level; }
public static N8Level GetHutProxies(string password=null) { N8Level Level = new N8Level(Utilities.GetDefaultSaveFolder() + "shrine_hut_final.ncd"); int counter = 500; foreach (N8Block b in Level.blocks.Blocks) { b.ID = counter; counter++; } Level.blocks.SetNextID(counter); Quaternion UpsideDown = new Quaternion(new Vector3D(1, 0, 0), 180); N8BlockFactory LevelBlocks = Level.blocks; List<Tuple<Vector3D, Quaternion>> targets = new List<Tuple<Vector3D, Quaternion>>(); List<Tuple<Vector3D, Quaternion>> proxies = new List<Tuple<Vector3D, Quaternion>>(); proxies.AddRange(Utilities.EvenCircle(new Vector3D(0, 0, -1), 45, 45)); proxies.Add(Tuple.Create(new Vector3D(50, 50, 50), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(-50, 50, 50), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(50, -50, 50), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(-50, -50, 50), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(-80, -80, 90), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(80, -80, 90), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(-80, 80, 90), new Quaternion())); proxies.Add(Tuple.Create(new Vector3D(80, 80, 90), new Quaternion())); //proxies.AddRange(Utilities.EvenSphere(new Vector3D(0, 0, 50), 60, 250, (double)8 / 16 * Math.PI)); for (int i = -160; i <= 160; i += 40) { for (int j = -40; j <= 40; j += 40) { proxies.Add(Tuple.Create(new Vector3D(i, j, 270), new Quaternion())); } } for (int i = -130; i <= 140; i += 45) { for (int j = -90; j <= 90; j += 45) { targets.Add(Tuple.Create(new Vector3D(i, j, 300), new Quaternion())); } } targets.AddRange(Utilities.EvenSphere(new Vector3D(0, 0, 50), 45, 50, (double)10 / 16 * Math.PI)); Quaternion ProxyRot = new Quaternion(new Vector3D(0, 0, 1), -90) * new Quaternion(new Vector3D(0, 1, 0), 90); Quaternion TargetRot = new Quaternion();//new Vector3D(0, 1, 0), -90); List<FlowTronic> alerts = new List<FlowTronic>(); for (int i = 0; i < proxies.Count; i++) { Tuple<Vector3D, Quaternion> t = proxies[i]; FlowTronic prox = LevelBlocks.Proxy("i=" + i); prox.position = t.Item1; alerts.Add(prox); } for (int i = 0; i < targets.Count; i++) { Tuple<Vector3D, Quaternion> t = targets[i]; FlowTronic target = LevelBlocks.Target("i=" + i); target.position = t.Item1; target.rotation = TargetRot * t.Item2; alerts.Add(target); } FleeTronics(LevelBlocks, alerts, false, true, password); //Console.WriteLine("Total number of blocks used: " + (LevelBlocks.Tronics.Count + LevelBlocks.Blocks.Count)); return Level; }
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()); } }
private void Materialize_Click(object sender, EventArgs e) { Materialize.Enabled = false; //Flip the heightmap's Y coordinates, because N8 uses y+ to mean up-screen and //everything else we've been doing so far uses Y+ to mean down-screen Terrain.Map.Map.ForEach((x) => x.Reverse()); //Assume that the cell will be tiled with CellSquareSize x CellSquareSize blocks int MaxCellSquareSize = (int)LandsPerCell.Value; //And then the number of cells in the X and Y direction... int NumCellsX = Terrain.Map.sizeX / MaxCellSquareSize; int NumCellsY = Terrain.Map.sizeY / MaxCellSquareSize; //And then reduce this map to whatever size we really want //Generate every map from 0 to what we have, so we can pick them out later. //That didn't work out :( I need to generate like a polygon surface or something and then tile it, not interpolate the points... List<Tuple<Heightmap, int>> maps = new List<Tuple<Heightmap, int>>(); Heightmap current = Terrain.Map; maps.Add(Tuple.Create(current, MaxCellSquareSize)); /* for (int i = MaxCellSquareSize; i >= 5; i--) { int CellSquareSize = i; //Reduce the map so each cell is CellSquareSize x CellSquareSize int newXSize = NumCellsX * CellSquareSize; int newYSize = NumCellsY * CellSquareSize; Heightmap fullmap = current.reduceTo(newXSize, newYSize); List<List<Heightmap>> map = Terrain.ChopHeightmap(CellSquareSize, fullmap); fullmap.ToHeatmap(CellSquareSize, null).Save(Utilities.GetDefaultSaveFolder() + @"terrain\heatmap," + CellSquareSize + ".png", System.Drawing.Imaging.ImageFormat.Png); maps.Add(Tuple.Create(fullmap, CellSquareSize)); current = fullmap; } */ Random rand = new Random(); //Pick which map to use; ideally, cells that need more detail will use a more detailed map. //Right now I'm just gonna generate them all and see how they vary by hand for (int CellSize = 0; CellSize < maps.Count; CellSize++) { Heightmap fullmap = maps[CellSize].Item1; int CellSquareSize = maps[CellSize].Item2; List<List<Heightmap>> CurrMap = Terrain.ChopHeightmap(CellSquareSize, fullmap); for (int k = 0; k < NumCellsX; k++) { for (int l = 0; l < NumCellsY; l++) { #region land placing setup //Given that square size, figure out how to (flat) tile a cell. //Each block will be cell size / square size in (effective) width and breadth. int BlockSize = 4000 / CellSquareSize; //If we have an even square size, we'll want to offset the block's position. int Offset = 0; if (CellSquareSize % 2 == 0) { Offset = BlockSize / 2; } //And we'll also need to calculate the offset to the edges of blocks, for rotation generation //But I'm not sure how to do that nicely, so I'll skip it for now. int BlockEdgeOffset = 0; if (CellSquareSize % 2 == 1) { BlockEdgeOffset = BlockSize / 2; } //Just set it to 0 in order to skip BlockEdgeOffset = 0; //And calculate the iterator offset, so we have everything in the middle int IterOffset = (CellSquareSize - 1) / 2; N8Level Level = new N8Level(); List<N8Block> lands = new List<N8Block>(CellSquareSize * CellSquareSize); Vector3D LowestPoint = new Vector3D(0, 0, int.MaxValue); string LandType = "land"; if (CellSquareSize < 10) { LandType = "landmega"; } #endregion #region placing lands for (int i = 0; i < CellSquareSize; i++) { for (int j = 0; j < CellSquareSize; j++) { N8Block land = Level.blocks.GenerateBlock(LandType, "Terrain"); land.position.X = ((i - IterOffset) * BlockSize) - Offset; land.position.Y = ((j - IterOffset) * BlockSize) - Offset; land.position.Z = CurrMap[k][l][i, j]; //Find the lowest point in the cell, but restrict it to near the center if (Math.Abs(land.position.X) < 1000 && Math.Abs(land.position.Y) < 1000) { if (land.position.Z < LowestPoint.Z) { LowestPoint = land.position; } } //Calculate the rotation - what we do is figure out what the //angle is between the south point and the north point, //then multiply that by the angle between the east point and west point. //North/South is Y +- 1, East/West is X +- 1 //We pull height information directly from the original heightmap because on the edges we'll need to get data from a different square. Vector3D North = new Vector3D(land.position.X, (((j + 1) - IterOffset) * BlockSize + BlockEdgeOffset), fullmap[k * CellSquareSize + i, l * CellSquareSize + (j + 1)]); Vector3D South = new Vector3D(land.position.X, (((j - 1) - IterOffset) * BlockSize + BlockEdgeOffset), fullmap[k * CellSquareSize + i, l * CellSquareSize + (j - 1)]); Vector3D East = new Vector3D((((i + 1) - IterOffset) * BlockSize + BlockEdgeOffset), land.position.Y, fullmap[k * CellSquareSize + (i + 1), l * CellSquareSize + j]); Vector3D West = new Vector3D((((i - 1) - IterOffset) * BlockSize + BlockEdgeOffset), land.position.Y, fullmap[k * CellSquareSize + (i - 1), l * CellSquareSize + j]); ; Vector3D LandPos = land.position; Quaternion NSRot = new Quaternion(0, 0, 0, 1); Quaternion EWRot = new Quaternion(0, 0, 0, 1); //If I'm between two things that are both higher or both lower than me, I shouldn't have a tilt in that direction. //E.G: if I'm like this : _-_ or -_-, I shouldn't have a tilt. if ((North.Z < LandPos.Z && LandPos.Z < South.Z) || (North.Z > LandPos.Z && LandPos.Z > South.Z)) { if ((North - South).Length > 400) { // land.type = "landmega"; } Vector3D higher = North; Vector3D lower = South; int dirMul = -1; if (South.Z > North.Z) { higher = South; lower = North; dirMul = 1; } Vector3D A = lower - new Vector3D(higher.X, higher.Y, lower.Z); Vector3D B = lower - new Vector3D(higher.X, higher.Y, higher.Z); A.Normalize(); B.Normalize(); NSRot = new Quaternion(new Vector3D(1, 0, 0), dirMul * Math.Acos(A.Z * B.Z + A.Y * B.Y) * Utilities.RadToDeg); } if ((East.Z < LandPos.Z && LandPos.Z < West.Z) || (West.Z < LandPos.Z && LandPos.Z < East.Z)) { if ((East - West).Length > 400) { // land.type = "landmega"; } Vector3D higher = West; Vector3D lower = East; int dirMul = -1; if (East.Z > West.Z) { higher = East; lower = West; dirMul = 1; } Vector3D A = lower - new Vector3D(higher.X, higher.Y, lower.Z); Vector3D B = lower - new Vector3D(higher.X, higher.Y, higher.Z); A.Normalize(); B.Normalize(); EWRot = new Quaternion(new Vector3D(0, 1, 0), dirMul * Math.Acos(A.Z * B.Z + A.X * B.X) * Utilities.RadToDeg); } land.rotation = EWRot * NSRot; lands.Add(land); } } #endregion //Utilities.Save(Utilities.GetDefaultSaveFolder() + @"terrain\plain\" + (k - BitmapOffset.X) + "," + (l - BitmapOffset.Y) + ".ncd", Level); Utilities.Save(Utilities.GetDefaultSaveFolder() + @"terrain\testing\" + (k - BitmapOffset.X) + "," + (l - BitmapOffset.Y) + ".ncd", Level); #region Extra nice things /* //Now add some nice things like a stack and random trees for (int b = -1000; b < LowestPoint.Z; b += 70) { N8Block stack = Level.blocks.GenerateBlock("floor", "Stack"); stack.position = LowestPoint; stack.position.Z = b; } Utilities.Save(Utilities.GetDefaultSaveFolder() + @"terrain\stack\" + (k - BitmapOffset.X) + "," + (l - BitmapOffset.Y) + ".ncd", Level); for (int b = 0; b < 75; b++) { //Pick a random piece of land N8Block currentLand = lands[rand.Next(lands.Count)]; //Put the tree's position in the middle of it Vector3D TreePos = new Vector3D(); TreePos = rand.NextVector(new Vector3D(-200, -200, 60), new Vector3D(200, 200, 70)); //Give it a random spin Quaternion rot = new Quaternion(new Vector3D(0, 0, 1), rand.Next(360)); //And finally materialize the tree N8Block tree = Level.blocks.GenerateBlock(Forest.TreeTypes[rand.Next() % Forest.TreeTypes.Length], Forest.TreeNames[rand.Next() % Forest.TreeNames.Length]); tree.position = TreePos; tree.rotation = rot; currentLand.AttachToMe(tree); } Utilities.Save(Utilities.GetDefaultSaveFolder() + @"terrain\tree\" + (k - BitmapOffset.X) + "," + (l - BitmapOffset.Y) + ".ncd", Level); // */ #endregion } } } //Unflip it, so we're back where we started Terrain.Map.Map.ForEach((x) => x.Reverse()); Terrain.Map.ToHeatmap(MaxCellSquareSize, null).Save(Utilities.GetDefaultSaveFolder() + @"terrain\heatmap.png", System.Drawing.Imaging.ImageFormat.Png); try { Terrain.Map.ToBitmap().Save(Utilities.GetDefaultSaveFolder() + @"terrain\heightmap.png", System.Drawing.Imaging.ImageFormat.Png); } catch (Exception) { MessageBox.Show("Warning, couldn't save heightmap"); } MessageBox.Show("Done!"); Materialize.Enabled = true; }