public ChunkSection(int dataVersion, Coord2 pos, byte y, long[] packedStates, BlockState[] palette) { Pos = pos; Y = y; Palette = palette; PackedBlockStates = packedStates; var paletteLength = palette.Length; paletteLength--; paletteLength |= paletteLength >> 1; paletteLength |= paletteLength >> 2; paletteLength |= paletteLength >> 4; paletteLength |= paletteLength >> 8; paletteLength |= paletteLength >> 16; paletteLength++; var bitWidth = Math.Max((int)Math.Log2(paletteLength), 4); BlockStates = new int[4096]; var isTightlyPacked = dataVersion < 2529; // 20w17a (2529) changed the data packing if (isTightlyPacked) { var bArr = new BitArray(packedStates.SelectMany(BitConverter.GetBytes).ToArray()); var bitIdx = 0; for (var i = 0; i < BlockStates.Length; i++) { BlockStates[i] = TakeBits(bArr, bitIdx, bitWidth); bitIdx += bitWidth; } } else { // In 20w17a+ the remaining bits in a long are left unused instead of // the data being split and rolling over into the next long var blocksPerLong = sizeof(long) * 8 / bitWidth; var longIdx = 0; var bitIdx = 0; BitArray bArr = null; for (var i = 0; i < BlockStates.Length; i++) { if (i % blocksPerLong == 0) { bArr = new BitArray(BitConverter.GetBytes(packedStates[longIdx])); longIdx++; bitIdx = 0; } BlockStates[i] = TakeBits(bArr, bitIdx, bitWidth); bitIdx += bitWidth; } } }
public static Chunk Load(NbtTree tag) { var dataVersion = tag.Root["DataVersion"].ToTagInt().Data; var level = tag.Root["Level"].ToTagCompound(); var sectionsList = level["Sections"].ToTagList(); if (sectionsList.Count == 0) { return(null); } var x = level["xPos"].ToTagInt().Data; var z = level["zPos"].ToTagInt().Data; var pos = new Coord2(x, z); var sections = sectionsList.Select(node => ChunkSection.Load(dataVersion, pos, node.ToTagCompound())).Where(section => section != null).ToArray(); var tiles = level["TileEntities"] .ToTagList() .Select(node => node.ToTagCompound()) .ToDictionary(node => new Coord3(node["x"].ToTagInt().Data, node["y"].ToTagInt().Data, node["z"].ToTagInt().Data), node => node); return(new Chunk(pos, sections, tiles)); }
public static ChunkSection Load(int dataVersion, Coord2 pos, TagNodeCompound tag) { var y = tag["Y"].ToTagByte().Data; if (!tag.ContainsKey("Palette")) { return(null); } var palette = tag["Palette"].ToTagList().Select(tagNode => BlockState.Load(tagNode.ToTagCompound())).ToArray(); var blockStates = tag["BlockStates"].ToTagLongArray().Data; return(new ChunkSection(dataVersion, pos, y, blockStates, palette)); }
public Chunk GetChunk(Coord2 chunkPos) { return(Chunks.ContainsKey(chunkPos) ? Chunks[chunkPos] : null); }
private Region(Coord2 pos, Dictionary <Coord2, Chunk> chunks) { Pos = pos; Chunks = chunks; }
public Chunk(Coord2 pos, ChunkSection[] sections, Dictionary <Coord3, TagNodeCompound> tiles) { Tiles = tiles; Pos = pos; Sections = sections; }
public Region GetRegion(Coord2 pos, string dimension = null) { return(GetRegion(new RegionId(pos, dimension))); }
public void Deconstruct(out Coord2 pos, out string dimension) { pos = Pos; dimension = Dimension; }
public RegionId(Coord2 pos, string dimension) { Pos = pos; Dimension = dimension; }