/// <summary> /// Generates and saves a single minecraft chunk using current settings. /// </summary> /// <param name="xi">X coordinate of the chunk.</param> /// <param name="zi">Y coordinate of the chunk.</param> public void generateSingleChunk(int xi, int zi) { // This line will create a default empty chunk, and create a // backing region file if necessary (which will immediately be // written to disk) ChunkRef chunk = currentWorld.GetChunkManager().CreateChunk(xi, zi); // This will make sure all the necessary things like trees and // ores are generated for us. chunk.IsTerrainPopulated = false; // Auto light recalculation is horrifically bad for creating // chunks from scratch, because we're placing thousands // of blocks. Turn it off. chunk.Blocks.AutoLight = false; double xMin = ((xi * 16.0 / (double)Settings.Default.blocksPerEmbarkTile) + Settings.Default.mapCenterX); double xMax = (((xi + 1) * 16.0 / (double)Settings.Default.blocksPerEmbarkTile) + Settings.Default.mapCenterX); double yMin = ((zi * 16.0 / (double)Settings.Default.blocksPerEmbarkTile) + Settings.Default.mapCenterY); double yMax = (((zi + 1) * 16.0 / (double)Settings.Default.blocksPerEmbarkTile) + Settings.Default.mapCenterY); // Make the terrain HeightMapChunk(chunk, xMin, xMax, yMin, yMax); // Reset and rebuild the lighting for the entire chunk at once chunk.Blocks.RebuildHeightMap(); chunk.Blocks.RebuildBlockLight(); chunk.Blocks.RebuildSkyLight(); // Save the chunk to disk so it doesn't hang around in RAM currentWorld.GetChunkManager().Save(); }
/// <summary> /// Generates and saves a single minecraft chunk using current settings. /// </summary> /// <param name="xi">X coordinate of the chunk.</param> /// <param name="zi">Y coordinate of the chunk.</param> public void generateSingleChunk(int xi, int zi) { // This line will create a default empty chunk, and create a // backing region file if necessary (which will immediately be // written to disk) ChunkRef chunk = currentWorld.GetChunkManager().CreateChunk(xi, zi); // This will make sure all the necessary things like trees and // ores are generated for us. chunk.IsTerrainPopulated = false; // Auto light recalculation is horrifically bad for creating // chunks from scratch, because we're placing thousands // of blocks. Turn it off. chunk.Blocks.AutoLight = false; // This scales the dimensions based off the blocksPerEmbarkTile [1..8] bounds bound = new bounds(xi, zi); // Make the terrain HeightMapChunk(chunk, bound); // Reset and rebuild the lighting for the entire chunk at once chunk.Blocks.RebuildHeightMap(); chunk.Blocks.RebuildBlockLight(); chunk.Blocks.RebuildSkyLight(); // Save the chunk to disk so it doesn't hang around in RAM currentWorld.GetChunkManager().Save(); }
List <ReaderWriterObjectLock <IChunk> > GetChunkLocks(IEnumerable <ChunkPositionDimension> positions) { lock (_chunkAccessLock) { var chunkLocks = new List <ReaderWriterObjectLock <IChunk> >(); foreach (var pos in positions) { ReaderWriterObjectLock <IChunk> chunkLock; if (_chunkAccess.TryGetValue(pos, out chunkLock)) { chunkLocks.Add(chunkLock); continue; } // create a new chunkLock if (_nbtWorld == null) { chunkLocks.Add(_chunkAccess[pos] = new ReaderWriterObjectLock <IChunk>(null)); continue; } var chunk = _nbtWorld.GetChunkManager(pos.Dimension).GetChunk(pos.ChunkX, pos.ChunkZ); chunkLocks.Add(_chunkAccess[pos] = new ReaderWriterObjectLock <IChunk>(chunk)); } return(chunkLocks); } }
public override void Run() { NbtWorld world = GetWorld(opt); IChunkManager cm = world.GetChunkManager(opt.OPT_DIM); FilteredChunkManager fcm = new FilteredChunkManager(cm, opt.GetChunkFilter()); int affectedChunks = 0; foreach (ChunkRef chunk in fcm) { if (chunk == null || !chunk.IsTerrainPopulated) { continue; } if (opt.OPT_V) { Console.WriteLine("Processing Chunk (" + chunk.X + "," + chunk.Z + ")"); } affectedChunks++; ApplyChunk(world, chunk); fcm.Save(); } Console.WriteLine("Affected Chunks: " + affectedChunks); }
private void button1_Click(object sender, EventArgs e) { Bitmap bm = new Bitmap(2048, 2176); NbtWorld world = NbtWorld.Open(@"E:\games\Curse\Instances\Modern Skyblock 2\saves\Kekimuro"); // The chunk manager is more efficient than the block manager for // this purpose, since we'll inspect every block Substrate.Core.IChunkManager rcm = world.GetChunkManager(); foreach (ChunkRef chunk in rcm) { // You could hardcode your dimensions, but maybe some day they // won't always be 16. Also the CLR is a bit stupid and has // trouble optimizing repeated calls to Chunk.Blocks.xx, so we // cache them in locals int xdim = chunk.Blocks.XDim; int ydim = chunk.Blocks.YDim; int zdim = chunk.Blocks.ZDim; AnvilBiomeCollection chunkBiome = chunk.Biomes; // x, z, y is the most efficient order to scan blocks (not that // you should care about internal detail) for (int x = 0; x < xdim; x++) { for (int z = 0; z < zdim; z++) { int biome = chunkBiome.GetBiome(x, z); bm.SetPixel(chunk.X * xdim + x, chunk.Z * zdim + z, Biomes.id2color(biome)); } } } pictureBox1.Image = bm; }
public override void Run() { NbtWorld world = GetWorld(opt); IChunkManager cm = world.GetChunkManager(opt.OPT_DIM); FilteredChunkManager fcm = new FilteredChunkManager(cm, opt.GetChunkFilter()); StreamWriter fstr; try { fstr = new StreamWriter(opt._outFile, false); } catch (IOException e) { Console.WriteLine(e.Message); return; } fstr.WriteLine("["); bool first = true; foreach (ChunkRef chunk in fcm) { if (!first) { fstr.Write(","); } Chunk c = chunk.GetChunkRef(); if (!opt._dumpBlocks) { c.Tree.Root["Level"].ToTagCompound().Remove("Blocks"); c.Tree.Root["Level"].ToTagCompound().Remove("Data"); c.Tree.Root["Level"].ToTagCompound().Remove("BlockLight"); c.Tree.Root["Level"].ToTagCompound().Remove("SkyLight"); c.Tree.Root["Level"].ToTagCompound().Remove("HeightMap"); } if (!opt._dumpEntities) { c.Tree.Root["Level"].ToTagCompound().Remove("Entities"); } if (!opt._dumpTileEntities) { c.Tree.Root["Level"].ToTagCompound().Remove("TileEntities"); } string s = JSONSerializer.Serialize(c.Tree.Root["Level"], 1); fstr.Write(s); first = false; } fstr.WriteLine(); fstr.WriteLine("]"); fstr.Close(); }
public mapReader(string mapFilePath) { nbtWorld = NbtWorld.Open(mapFilePath); chunkManager = nbtWorld.GetChunkManager(); chunkEnumerator = chunkManager.GetEnumerator(); chunkEnumerator.MoveNext(); CurrentChunk = chunkEnumerator.Current; CurrentHeight = 0; readASlice(); }
static void Main(string[] args) { if (args.Length != 3) { Console.WriteLine("Usage: BlockReplace <world> <before-id> <after-id>"); return; } string dest = args[0]; int before = Convert.ToInt32(args[1]); int after = Convert.ToInt32(args[2]); // Open our world NbtWorld world = NbtWorld.Open(dest); // The chunk manager is more efficient than the block manager for // this purpose, since we'll inspect every block IChunkManager cm = world.GetChunkManager(); foreach (ChunkRef chunk in cm) { // You could hardcode your dimensions, but maybe some day they // won't always be 16. Also the CLR is a bit stupid and has // trouble optimizing repeated calls to Chunk.Blocks.xx, so we // cache them in locals int xdim = chunk.Blocks.XDim; int ydim = chunk.Blocks.YDim; int zdim = chunk.Blocks.ZDim; // x, z, y is the most efficient order to scan blocks (not that // you should care about internal detail) for (int x = 0; x < xdim; x++) { for (int z = 0; z < zdim; z++) { for (int y = 0; y < ydim; y++) { // Replace the block with after if it matches before if (chunk.Blocks.GetID(x, y, z) == before) { chunk.Blocks.SetData(x, y, z, 0); chunk.Blocks.SetID(x, y, z, after); } } } } // Save the chunk cm.Save(); Console.WriteLine("Processed Chunk {0},{1}", chunk.X, chunk.Z); } }
static void Main(string[] args) { if (args.Length != 2) { Console.WriteLine("Usage: GoodyChest <world> <prob>"); return; } string dest = args[0]; double p = Convert.ToDouble(args[1]); rand = new Random(); // Open our world NbtWorld world = NbtWorld.Open(dest); IChunkManager cm = world.GetChunkManager(); int added = 0; // Iterate through every chunk in the world // With proability p, pick a random location // inside the chunk to place a chest, above the // first solid block foreach (ChunkRef chunk in cm) { if (rand.NextDouble() < p) { int x = rand.Next(chunk.Blocks.XDim); int z = rand.Next(chunk.Blocks.ZDim); int y = chunk.Blocks.GetHeight(x, z); // Can't build this high (-2 to account for new MC 1.6 height limitation) if (y >= chunk.Blocks.YDim - 2) { continue; } // Get a block object, then assign it to the chunk AlphaBlock block = BuildChest(); chunk.Blocks.SetBlock(x, y + 1, z, block); // Save the chunk cm.Save(); added++; } } // And we're done Console.WriteLine("Added {0} goody chests to world", added); }
static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("You must specify a target directory"); return; } string dest = args[0]; NbtVerifier.InvalidTagType += (e) => { throw new Exception("Invalid Tag Type: " + e.TagName + " [" + e.Tag + "]"); }; NbtVerifier.InvalidTagValue += (e) => { throw new Exception("Invalid Tag Value: " + e.TagName + " [" + e.Tag + "]"); }; NbtVerifier.MissingTag += (e) => { throw new Exception("Missing Tag: " + e.TagName); }; // Opening an NbtWorld will try to autodetect if a world is Alpha-style or Beta-style NbtWorld world = NbtWorld.Open(dest); // Grab a generic chunk manager reference IChunkManager cm = world.GetChunkManager(); // First blank out all of the lighting in all of the chunks foreach (ChunkRef chunk in cm) { chunk.Blocks.RebuildHeightMap(); chunk.Blocks.ResetBlockLight(); chunk.Blocks.ResetSkyLight(); cm.Save(); Console.WriteLine("Reset Chunk {0},{1}", chunk.X, chunk.Z); } // In a separate pass, reconstruct the light foreach (ChunkRef chunk in cm) { chunk.Blocks.RebuildBlockLight(); chunk.Blocks.RebuildSkyLight(); // Save the chunk to disk so it doesn't hang around in RAM cm.Save(); Console.WriteLine("Lit Chunk {0},{1}", chunk.X, chunk.Z); } }
static void Main(string[] args) { if (args.Length != 3) { Console.WriteLine("Usage: Convert <world> <dest> <alpha|beta|anvil>"); return; } string src = args[0]; string dst = args[1]; string srctype = args[2]; if (!Directory.Exists(dst)) { Directory.CreateDirectory(dst); } // Open source and destrination worlds depending on conversion type NbtWorld srcWorld = NbtWorld.Open(src); NbtWorld dstWorld; switch (srctype) { case "alpha": dstWorld = AlphaWorld.Create(dst); break; case "beta": dstWorld = BetaWorld.Create(dst); break; case "anvil": dstWorld = AnvilWorld.Create(dst); break; default: throw new Exception("Invalid conversion type"); } // Grab chunk managers to copy chunks IChunkManager cmsrc = srcWorld.GetChunkManager(); IChunkManager cmdst = dstWorld.GetChunkManager(); // Copy each chunk from source to dest foreach (ChunkRef chunk in cmsrc) { cmdst.SetChunk(chunk.X, chunk.Z, chunk.GetChunkRef()); Console.WriteLine("Copying chunk: {0}, {1}", chunk.X, chunk.Z); } // Copy level data from source to dest dstWorld.Level.LoadTreeSafe(srcWorld.Level.BuildTree()); // Save level.dat dstWorld.Level.Save(); }
public override void Run() { NbtWorld world = GetWorld(opt); IChunkManager cm = world.GetChunkManager(opt.OPT_DIM); FilteredChunkManager fcm = new FilteredChunkManager(cm, opt.GetChunkFilter()); int affectedChunks = 0; foreach (ChunkRef chunk in fcm) { affectedChunks++; fcm.DeleteChunk(chunk.X, chunk.Z); } Console.WriteLine("Purged Chunks: " + affectedChunks); }
static void Main(string[] args) { if (args.Length != 1) { Console.WriteLine("Usage: CustomBlock <world>"); return; } string dest = args[0]; // Open our world NbtWorld world = NbtWorld.Open(dest); // The chunk manager is more efficient than the block manager for // this purpose, since we'll inspect every block IChunkManager cm = world.GetChunkManager(); foreach (ChunkRef chunk in cm) { // You could hardcode your dimensions, but maybe some day they // won't always be 16. Also the CLR is a bit stupid and has // trouble optimizing repeated calls to Chunk.Blocks.xx, so we // cache them in locals int xdim = chunk.Blocks.XDim; int ydim = chunk.Blocks.YDim; int zdim = chunk.Blocks.ZDim; chunk.Blocks.AutoFluid = true; // x, z, y is the most efficient order to scan blocks (not that // you should care about internal detail) for (int x = 0; x < xdim; x++) { for (int z = 0; z < zdim; z++) { for (int y = 0; y < ydim; y++) { BlockInfo info = chunk.Blocks.GetInfo(x, y, z); if (info.ID == BlockInfoM.LightSensor.ID) { Console.WriteLine("Found custom block '{0}' at {1}", info.Name, new BlockKey(x, y, z)); } } } } } }
static void Main(string[] args) { // Process arguments if (args.Length != 2 && args.Length != 6) { Console.WriteLine("Usage: PurgeEntities <world> <entityID> [<x1> <z1> <x2> <z2>]"); return; } string dest = args[0]; string eid = args[1]; // Our initial bounding box is "infinite" int x1 = BlockManager.MIN_X; int x2 = BlockManager.MAX_X; int z1 = BlockManager.MIN_Z; int z2 = BlockManager.MAX_Z; // If we have all coordinate parameters, set the bounding box if (args.Length == 6) { x1 = Convert.ToInt32(args[2]); z1 = Convert.ToInt32(args[3]); x2 = Convert.ToInt32(args[4]); z2 = Convert.ToInt32(args[5]); } // Load world NbtWorld world = NbtWorld.Open(dest); IChunkManager cm = world.GetChunkManager(); // Remove entities foreach (ChunkRef chunk in cm) { // Skip chunks that don't cover our selected area if (((chunk.X + 1) * chunk.Blocks.XDim < x1) || (chunk.X * chunk.Blocks.XDim >= x2) || ((chunk.Z + 1) * chunk.Blocks.ZDim < z1) || (chunk.Z * chunk.Blocks.ZDim >= z2)) { continue; } // Delete the specified entities chunk.Entities.RemoveAll(eid); cm.Save(); } }
//NbtWorld nbtWorld; public MCALoaderChunkGeneratorJob(bool useID, NbtWorld nbtWorld, string savePath, int x, int ySize, int z, List <Chunk> chunksFromYBottomToTop) : base(chunksFromYBottomToTop) { this.useID = useID; this.x = x; this.ySize = ySize; this.z = z; //this.nbtWorld = nbtWorld; if (cmPool == null) { cmPool = new Matryoshka.Utils.PerThreadPool <IChunkManager>(() => { //return NbtWorld.Open(savePath).GetChunkManager(); return(nbtWorld.GetChunkManager()); }); } this.isUnique = false; }
public override void Run() { NbtWorld world = GetWorld(opt); IChunkManager cm = world.GetChunkManager(opt.OPT_DIM); FilteredChunkManager fcm = new FilteredChunkManager(cm, opt.GetChunkFilter()); int affectedChunks = 0; foreach (ChunkRef chunk in fcm) { if (opt.OPT_V) { Console.WriteLine("Processing chunk {0},{1}...", chunk.X, chunk.Z); } ApplyChunk(world, chunk); affectedChunks += fcm.Save() > 0 ? 1 : 0; } Console.WriteLine("Affected Chunks: " + affectedChunks); }
ReaderWriterObjectLock <IChunk> GetChunkLock(ChunkPositionDimension pos) { lock (_chunkAccessLock) { ReaderWriterObjectLock <IChunk> chunkLock; if (_chunkAccess.TryGetValue(pos, out chunkLock)) { return(chunkLock); } // create a new chunkLock if (NbtWorld == null) { return(_chunkAccess[pos] = new ReaderWriterObjectLock <IChunk>(null)); } var chunk = NbtWorld.GetChunkManager(pos.Dimension).GetChunk(pos.ChunkX, pos.ChunkZ); return(_chunkAccess[pos] = new ReaderWriterObjectLock <IChunk>(chunk)); } }
public void Run() { Console.Clear(); var cm = _world.GetChunkManager(); _totalChunks = cm.Count(); Console.WriteLine("# Chunks: {0}", _totalChunks); Task.WaitAll(cm.Select(chunkRef => Task.Factory.StartNew(() => ProcessChunk(chunkRef))).ToArray()); Console.WriteLine(); foreach (var block in _blockArgs) { block.PrintValues(_totalChunks); Console.WriteLine(); Console.WriteLine(); } }
public override void Run() { if (!Directory.Exists(opt.OPT_WORLD) && !File.Exists(opt.OPT_WORLD)) { Console.WriteLine("Error: Could not locate path: " + opt.OPT_WORLD); return; } NbtWorld world = null; IChunkManager cm = null; FilteredChunkManager fcm = null; try { world = NbtWorld.Open(opt.OPT_WORLD); cm = world.GetChunkManager(opt.OPT_DIM); fcm = new FilteredChunkManager(cm, opt.GetChunkFilter()); } catch (Exception e) { Console.WriteLine("Error: Failed to open world: " + opt.OPT_WORLD); Console.WriteLine("Exception: " + e.Message); Console.WriteLine(e.StackTrace); return; } int affectedChunks = 0; foreach (ChunkRef chunk in fcm) { if (opt.OPT_V) { Console.WriteLine("Processing chunk {0},{1}...", chunk.X, chunk.Z); } ApplyChunk(world, chunk); affectedChunks += fcm.Save() > 0 ? 1 : 0; } Console.WriteLine("Affected Chunks: " + affectedChunks); }
public static void SetBiomeData(string dest) { NbtWorld world = NbtWorld.Open(dest); IChunkManager cm = world.GetChunkManager(); foreach (ChunkRef chunk in cm) { AnvilChunk anvil_chunk = chunk.GetChunkRef() as AnvilChunk; TagNodeByteArray biomeNode = anvil_chunk.Tree.Root["Level"].ToTagCompound()["Biomes"].ToTagByteArray(); ZXByteArray biomeData = new ZXByteArray(16, 16, biomeNode.Data); for (int x = 0; x <= 15; x++) { for (int y = 0; y <= 15; y++) { biomeData[x, y] = biomes[chunk.X + "." + chunk.Z]; } } chunk.SetChunkRef(anvil_chunk); cm.Save(); } world.Save(); }
public void ApplyChunk(NbtWorld world, ChunkRef chunk) { if (opt.OPT_V) { Console.WriteLine("Generating {0} size {1} deposits of {2} between {3} and {4}", opt.OPT_ROUNDS, opt.OPT_SIZE, opt.OPT_ID, opt.OPT_MIN, opt.OPT_MAX); } IGenerator generator; if (opt.OPT_DATA == null) { generator = new NativeGenOre((int)opt.OPT_ID, (int)opt.OPT_SIZE); ((NativeGenOre)generator).MathFix = opt.OPT_MATHFIX; } else { generator = new NativeGenOre((int)opt.OPT_ID, (int)opt.OPT_DATA, (int)opt.OPT_SIZE); ((NativeGenOre)generator).MathFix = opt.OPT_MATHFIX; } IChunkManager cm = world.GetChunkManager(opt.OPT_DIM); IBlockManager bm = new GenOreBlockManager(cm, opt); for (int i = 0; i < opt.OPT_ROUNDS; i++) { if (opt.OPT_VV) { Console.WriteLine("Generating round {0}...", i); } int x = chunk.X * chunk.Blocks.XDim + rand.Next(chunk.Blocks.XDim); int y = (int)opt.OPT_MIN + rand.Next((int)opt.OPT_MAX - (int)opt.OPT_MIN); int z = chunk.Z * chunk.Blocks.ZDim + rand.Next(chunk.Blocks.ZDim); generator.Generate(bm, rand, x, y, z); } }
static void Main(string[] args) { if (args.Length < 2) { Console.WriteLine("Usage: eina_to_nbt <source> <dest>"); return; } String dest = args[1]; System.Console.WriteLine("Creating EINA map..."); if (!Directory.Exists(dest)) { Directory.CreateDirectory(dest); } NbtWorld world = AnvilWorld.Create(dest); world.Level.LevelName = "EINA"; world.Level.Spawn = new SpawnPoint(292, 70, 270); world.Level.GameType = GameType.CREATIVE; world.Level.Initialized = true; Player p = new Player(); p.Position.X = 292; p.Position.Y = 130; p.Position.Z = 292; IPlayerManager pm = world.GetPlayerManager(); pm.SetPlayer("Player", p); IChunkManager cm = world.GetChunkManager(); string[] lines = System.IO.File.ReadAllLines(args[0]); string[] words; ChunkRef chunk; words = lines[0].Split(' '); int minx = Int32.Parse(words[0]); int maxx = Int32.Parse(words[0]); int miny = Int32.Parse(words[0]); int maxy = Int32.Parse(words[0]); for (int i = 0; i < lines.Length; i++) { words = lines[i].Split(' '); //System.Console.WriteLine(lines[i]); int x = Int32.Parse(words[0]); int y = Int32.Parse(words[1]); int z = Int32.Parse(words[2]); int color = Int32.Parse(words[3]); string text = ""; if (words.Length > 4) { text = words[4]; for (int j = 5; j < words.Length; j++) { text += ' ' + words[j]; } } else { text = ""; } int xLocal = x / 16; int yLocal = y / 16; if (xLocal < minx) { minx = xLocal; } if (xLocal > maxx) { maxx = xLocal; } if (yLocal < miny) { miny = yLocal; } if (yLocal > maxy) { maxy = yLocal; } if (!cm.ChunkExists(xLocal, yLocal)) { //System.Console.WriteLine(xLocal+" "+yLocal); cm.CreateChunk(xLocal, yLocal); } chunk = cm.GetChunkRef(xLocal, yLocal); //System.Console.WriteLine(x+" "+y+" "+z); //System.Console.WriteLine(xLocal+" "+yLocal); if (!chunk.IsDirty) { chunk.IsTerrainPopulated = true; chunk.Blocks.AutoLight = false; //FlatChunk(chunk, 64); chunk.Blocks.RebuildHeightMap(); chunk.Blocks.RebuildBlockLight(); chunk.Blocks.RebuildSkyLight(); //System.Console.WriteLine(chunk.IsDirty); for (int i2 = 0; i2 < 16; i2++) { for (int j = 0; j < 16; j++) { setBlock(chunk, i2, 64, j, 16, ""); } } if (((xLocal % 8) == 0) & ((yLocal % 8) == 0)) { cm.Save(); } setBlock(chunk, x % 16, z + 64, y % 16, color, text); } else { setBlock(chunk, x % 16, z + 64, y % 16, color, text); //System.Console.WriteLine("hola"); } if ((i + 1) % 500000 == 0) { System.Console.WriteLine("Guardando"); world.Save(); //System.Console.WriteLine("Hecho"); } } world.Save(); }
/// <summary> /// Trims the world to work with only the chuncks within the coordents. /// </summary> /// <param name="xStart"></param> /// <param name="zStart"></param> /// <param name="xEnd"></param> /// <param name="zEnd"></param> /// <param name="yTop"></param> /// <param name="yBottom"></param> /// <returns></returns> public static bool TrimWorld() { //Clear trimmed chunks list TrimedChunks = new List <SimpleChunkRef>(); //Get the higher X int HighX = xStart / 16; int LowX = xEnd / 16; if (xEnd > xStart) { HighX = xEnd / 16; LowX = xStart / 16; } //Get the higher Z int HighZ = zStart / 16; int LowZ = zEnd / 16; if (zEnd > zStart) { HighZ = zEnd / 16; LowZ = zStart / 16; } //Loop through world and grab chuncks IChunkManager cm = importedWorld.GetChunkManager(); for (int x = LowX; x <= HighX; x++) { for (int z = LowZ; z <= HighZ; z++) { string signX = "+"; if (z < 0) { signX = "-"; } string signZ = "+"; if (z < 0) { signZ = "-"; } if (cm.ChunkExists(x, z)) { IChunk chunk = cm.GetChunk(x, z); //Console.WriteLine("Saving: xz[{0}{1},{2}{3}]", signX, Math.Abs(x).ToString("D3"), signZ, Math.Abs(z).ToString("D3")); TrimedChunks.Add(new SimpleChunkRef(x, z, chunk)); } else { //Console.WriteLine("No chunk found: xz[{0}{1},{2}{3}]", signX, Math.Abs(x).ToString("D3"), signZ, Math.Abs(z).ToString("D3")); TrimedChunks.Add(new SimpleChunkRef(x, z, null)); } } } if (TrimedChunks.Count > 0) { return(true); } else { return(false); } }
private static void LoopChunks(NbtWorld world, int dim) { DateTime startTime = DateTime.Now; Console.WriteLine("Searching {0}", dimensions[dim]); int fixedChests = 0; int fixedPotions = 0; int fixedSpawners = 0; IChunkManager chunks = world.GetChunkManager(dim); foreach (ChunkRef chunk in chunks) { for (int x = 0; x < chunk.Blocks.XDim; x++) { for (int z = 0; z < chunk.Blocks.ZDim; z++) { for (int y = 0; y < chunk.Blocks.YDim; y++) { switch (chunk.Blocks.GetID(x, y, z)) { case BlockType.CHEST: if (FixChest(chunk, x, y, z)) { Console.WriteLine("Fixed chest"); fixedChests++; } if (fixPotions) { fixedPotions += FixPotions(chunk, x, y, z); } break; case BlockType.DISPENSER: if (fixPotions) { fixedPotions += FixPotions(chunk, x, y, z); } break; case BlockType.BREWING_STAND: if (fixPotions) { fixedPotions += FixPotions(chunk, x, y, z); } break; case BlockType.MONSTER_SPAWNER: if (fixSpawners && FixSpawner(chunk, x, y, z)) { Console.WriteLine("Fixed Spawner"); fixedSpawners++; } break; } } } } chunks.Save(); } TimeSpan time = DateTime.Now.Subtract(startTime); Console.Write("Finished searching {0} in {1}. Fixed:", dimensions[dim], time.ToString(@"h\:mm\:ss")); Console.Write(" [{0} chest{1}]", fixedChests, fixedChests == 1 ? "" : "s"); Console.Write(" [{0} potion{1}]", fixedPotions, fixedPotions == 1 ? "" : "s"); Console.Write(" [{0} potion spawner{1}]", fixedSpawners, fixedSpawners == 1 ? "" : "s"); Console.WriteLine(); fixedIssues["chest"] += fixedChests; fixedIssues["potion"] += fixedPotions; fixedIssues["spawner"] += fixedSpawners; }
public override void Run() { NbtWorld world = GetWorld(opt); IChunkManager cm = world.GetChunkManager(opt.OPT_DIM); FilteredChunkManager fcm = new FilteredChunkManager(cm, opt.GetChunkFilter()); if (opt.OPT_V) { Console.WriteLine("Clearing existing chunk lighting..."); } int affectedChunks = 0; foreach (ChunkRef chunk in fcm) { if (opt.OPT_VV) { Console.WriteLine("Resetting chunk {0},{1}...", chunk.X, chunk.Z); } if (opt.HeightMap) { chunk.Blocks.RebuildHeightMap(); } if (opt.BlockLight) { chunk.Blocks.ResetBlockLight(); } if (opt.SkyLight) { chunk.Blocks.ResetSkyLight(); } fcm.Save(); affectedChunks++; } if (opt.OPT_V) { Console.WriteLine("Rebuilding chunk lighting..."); } foreach (ChunkRef chunk in fcm) { if (opt.OPT_VV) { Console.WriteLine("Lighting chunk {0},{1}...", chunk.X, chunk.Z); } if (opt.BlockLight) { chunk.Blocks.RebuildBlockLight(); } if (opt.SkyLight) { chunk.Blocks.RebuildSkyLight(); } fcm.Save(); } if (opt.OPT_V) { Console.WriteLine("Reconciling chunk edges..."); } foreach (ChunkRef chunk in fcm) { if (opt.OPT_VV) { Console.WriteLine("Stitching chunk {0},{1}...", chunk.X, chunk.Z); } if (opt.BlockLight) { chunk.Blocks.StitchBlockLight(); } if (opt.SkyLight) { chunk.Blocks.StitchSkyLight(); } fcm.Save(); } Console.WriteLine("Relit Chunks: " + affectedChunks); }
public World ConvertWorld(String mcDirectory) { String segmentDirectory = Path.Combine(FCEDirectory, "Segments"); if (!Directory.Exists(FCEDirectory)) { Directory.CreateDirectory(FCEDirectory); } if (!Directory.Exists(Path.Combine(FCEDirectory, segmentDirectory))) { Directory.CreateDirectory(segmentDirectory); } Boolean anvil = true; NbtWorld nbtWorld = AnvilWorld.Open(mcDirectory); String worldName = nbtWorld.Level.LevelName; IChunkManager chunkManager = nbtWorld.GetChunkManager(); try { // Try to test for mc world type // Don't know how this is supposed to work, but it presumably throws an exception // on a non-Anvil world. chunkManager.Count(); } catch { anvil = false; nbtWorld = BetaWorld.Open(mcDirectory); worldName = nbtWorld.Level.LevelName; chunkManager = nbtWorld.GetChunkManager(); } Int32 spawnChunkX = nbtWorld.Level.Spawn.X >> 4; Int32 spawnChunkZ = nbtWorld.Level.Spawn.Z >> 4; WorldSettings settings = new WorldSettings(); settings.Name = worldName; var fceWorld = World.Create(FCEDirectory, settings); var segmentManager = fceWorld.SegmentManager; _totalSegments = chunkManager.LongCount() * (anvil ? 16 : 8); _segmentsLeft = _totalSegments; StartSaveThread(fceWorld); foreach (ChunkRef chunk in chunkManager) { // If the save thread is too slow, wait until it has caught up before adding to it to prevent high ram usage while (_saveQueue.Count > 5000) { Thread.Sleep(500); } if (chunk.Blocks == null) { _segmentsLeft -= (anvil ? 16 : 8); continue; } Int32 spawnOffsetX = UseSpawnAsOrigin ? spawnChunkX - chunk.X : -chunk.X; Int32 spawnOffsetZ = UseSpawnAsOrigin ? spawnChunkZ - chunk.Z : -chunk.Z; // Minecraft has different x/y directions so we must reverse z so the world isn't mirrored var chunkCoords = new SegmentCoords(spawnOffsetX, 0, -spawnOffsetZ) + SegmentCoords.WorldCenter; for (Int32 i = 0; i < (anvil ? 16 : 8); i++) { SegmentCoords segCoords = chunkCoords + SegmentCoords.Above * i; var segment = new Segment(segmentManager, segCoords); var array = new Cube[16, 16, 16]; for (Byte x = 0; x < 16; x++) { for (Byte y = 0; y < 16; y++) { for (Byte z = 0; z < 16; z++) { // Minecraft has different x/y directions so we must reverse z so the world isn't mirrored AlphaBlock block = chunk.Blocks.GetBlock(15 - z, y + i * 16, x); UInt32 mcIdData = (UInt32)block.ID << 16 | (UInt16)block.Data; Cube cube; if (!_mcIdDataToFCECube.TryGetValue(mcIdData, out cube)) { cube = new Cube(1, 0, 0, 0); if (!UnknownBlocks.ContainsKey((UInt16)block.ID)) { UnknownBlocks.Add((UInt16)block.ID, block.Info.Name); } } array[z, y, x] = cube; } } } segment.CubeData = array; _segmentsLeft--; _saveQueue.Enqueue(segment); } // Pad the area above the converted world with 11 blank segments to prevent world gen from occuring // Possibly replace this in the future with simply shifting the world up for (Int32 i = (anvil ? 16 : 8); i < 27; i++) { var padding = new Segment(segmentManager, chunkCoords + SegmentCoords.Above * i); padding.CubeData = Segment.GetBlankSegment().CubeData; padding.IsEmpty = true; _saveQueue.Enqueue(padding); } } Task.WaitAll(_saveTask); return(fceWorld); }