public static bool IsBlockForMap(ProtoBlock b, HeightmapType type) { if (b == null || IsAir(b)) { return(false); } if (type == HeightmapType.AllBlocks) { return(true); } else if (type == HeightmapType.SolidBlocks) { return(!IsTransparentBlock(b)); } else if (type == HeightmapType.SolidBlocksNoLiquid) { return(!IsTransparentBlock(b) && !IsLiquid(b) && !b.Compare("minecraft:ice")); } else if (type == HeightmapType.TerrainBlocks) { return(b.CompareMultiple(commonTerrainBlocks) || b.CompareMultiple(waterBlock, lavaBlock)); } else if (type == HeightmapType.TerrainBlocksNoLiquid) { return(b.CompareMultiple(commonTerrainBlocks)); } else { return(false); } }
///<summary>Writes the chunk's height data to a large heightmap at the given chunk coords</summary> public void WriteToHeightmap(short[,] hm, int x, int z, HeightmapType type) { if (!WriteHeightmapFromNBT(hm, x, z, type)) { WriteHeightmapFromBlocks(hm, x, z, type); } }
public ISequenceAccessor <int> GetAccessor(HeightmapType type = HeightmapType.Default) { switch (State) { case AttributeVersion.Pre113: if (type != HeightmapType.LightBlocking && type != HeightmapType.Default) { throw new NotSupportedException(); } return(new ArraySeqAccessor <int>(ClassicHeightMap)); case AttributeVersion.Post113: if (type == HeightmapType.Default) { type = HeightmapType.WorldSurface; } if (HeightMaps[(int)type] == null) { return(null); } return(HeightMaps[(int)type]); case AttributeVersion.NotCalculated: return(null); default: throw new NotSupportedException(); } }
public static HeightData ImportHeightmap(string filepath, HeightmapType type) { ushort[,] hms = RegionImporter.GetHeightmap(filepath, type); HeightData asc = new HeightData(512, 512, filepath); for (int x = 0; x < 512; x++) { for (int z = 0; z < 512; z++) { asc.SetHeight(x, z, hms[x, 511 - z]); } } asc.filename = Path.GetFileNameWithoutExtension(filepath); asc.cellSize = 1; asc.nodata_value = -9999; asc.RecalculateValues(false); asc.lowPoint = 0; asc.highPoint = 255; asc.isValid = true; ConsoleOutput.WriteLine("Lowest: " + asc.lowestValue); ConsoleOutput.WriteLine("Hightest: " + asc.highestValue); asc.lowestValue = 0; asc.highestValue = 255; return(asc); }
public Heightmap(HeightmapType type, Chunk chunk) { this.HeightmapType = type; this.chunk = chunk; if (type == HeightmapType.MotionBlocking) { this.Predicate = (block) => block.NotAir() || block.NotFluid(); } }
public short[,] GetHeightmap(HeightmapType type, bool keepFlippedZ) { var hm = world.GetHeightmap(worldBounds.xMin, worldBounds.yMin, worldBounds.xMax, worldBounds.yMax, type); if (!keepFlippedZ) { hm = ArrayConverter.Flip(hm); } return(hm); }
public Heightmap(HeightmapType type, Chunk chunk) { this.HeightmapType = type; this.chunk = chunk; if (type == HeightmapType.MotionBlocking) { this.Predicate = (block) => !block.IsAir || !block.IsFluid; } }
/// <summary> /// Generates a Heightmap from the specified area (With Z starting from top) /// </summary> public short[,] GetHeightmap(int xMin, int zMin, int xMax, int zMax, HeightmapType type) { short[,] hm = new short[xMax - xMin + 1, zMax - zMin + 1]; for (int z = zMin; z <= zMax; z++) { for (int x = xMin; x <= xMax; x++) { hm[x - xMin, z - zMin] = GetRegionAt(x, z)?.GetChunk(x % 512, z % 512, false)?.GetHighestBlock(x % 16, z % 16, type) ?? short.MinValue; } } return(hm); }
/// <summary> /// Gets the highest block at the given location. /// </summary> public short GetHighestBlock(int x, int z, HeightmapType heightmapType = HeightmapType.AllBlocks) { var chunk = GetChunk(x, z, false); if (chunk != null) { return(chunk.GetHighestBlock(x % 16, z % 16, heightmapType)); } else { return(short.MinValue); } }
public short GetHighestBlock(int chunkX, int chunkZ, HeightmapType type = HeightmapType.AllBlocks) { short y = (short)(HighestSection * 16 + 15); while (y >= LowestSection * 16) { if (Blocks.IsBlockForMap(GetBlockAt(chunkX, y, chunkZ).block, type)) { return(y); } y--; } return(short.MinValue); }
private Heightmap(HeightmapType type, Chunk chunk, DataArray data) { HeightmapType = type; this.chunk = chunk; this.data = data; if (type == HeightmapType.MotionBlocking) { Predicate = (block) => !block.IsAir || !block.IsFluid; } else { Predicate = _ => false; } }
public OverviewmapExporter(MCWorldExporter world, bool mcMapStyle, HeightmapType type = HeightmapType.SolidBlocks) { var heightmap = world.GetHeightmap(type, true); HeightData heightData = new HeightData(ArrayConverter.ToFloatMap(ArrayConverter.Flip(heightmap)), 1) { lowPoint = 0, highPoint = 256 }; map = world.world.GetSurfaceMap(world.worldBounds.xMin, world.worldBounds.yMin, heightmap, mcMapStyle); if (!mcMapStyle) { map = GenerateShadedMap(heightData, map); } }
public Heightmap(HeightmapType type, Chunk chunk) { HeightmapType = type; this.chunk = chunk; data = new DataArray(9, 256); if (type == HeightmapType.MotionBlocking) { Predicate = (block) => !block.IsAir || !block.IsFluid; } else { Predicate = _ => false; } }
///<summary>Generates a heightmap by reading the chunk's heightmaps or calculating it from existing blocks.</summary> public short[,] GetHeightmapFromNBT(HeightmapType type) { short[,] hm = new short[512, 512]; for (int x = 0; x < 32; x++) { for (int z = 0; z < 32; z++) { var c = chunks[x, z]; if (c != null) { c.WriteToHeightmap(hm, x, z, type); } } } return(hm); }
public IEnumerable <(int X, int Z, int Height)> AllHeights(HeightmapType type = HeightmapType.Default) { var index = 0; switch (State) { case AttributeVersion.Pre113: if (type != HeightmapType.LightBlocking && type != HeightmapType.Default) { throw new NotSupportedException(); } for (var z = 0; z < 16; z++) { for (var x = 0; x < 16; x++) { yield return(x, z, ClassicHeightMap[index++]);
///<summary>Reads the height data from a region (With [0,0] being the top-left corner).</summary> public static short[,] GetHeightmap(string filepath, HeightmapType heightmapType) { short[,] heightmap = new short[512, 512]; RegionData rd; using (var stream = File.Open(filepath, FileMode.Open)) { rd = new RegionData(stream, filepath); } //TODO: make parallel after testing for (int i = 0; i < 1024; i++) { if (rd.compressedChunks[i] != null) { var cd = rd.compressedChunks[i]; using (var chunkStream = CreateZLibDecompressionStream(cd.compressedChunk)) { WriteChunkToHeightmap(heightmap, new NBTContent(chunkStream), i % 32, i / 32, heightmapType); } } } return(heightmap); }
/// <summary> /// Generates a colored overview map from the specified area (With Z starting from top) /// </summary> public Bitmap GetSurfaceMap(int xMin, int zMin, int xMax, int zMax, HeightmapType surfaceType, bool shading) { return(GetSurfaceMap(xMin, zMin, GetHeightmap(xMin, zMin, xMax, zMax, surfaceType), shading)); }
public static Bitmap GetSurfaceMap(string filepath, HeightmapType surfaceType, bool mcMapShading) { Region r = LoadRegion(filepath); var hm = r.GetHeightmapFromNBT(surfaceType); for (int z = 0; z < 512; z++) { for (int x = 0; x < 512; x++) { short y = hm[x, z]; while (!Blocks.IsBlockForMap(r.GetBlock(x, y, z), surfaceType) && y > 0) { y--; } hm[x, z] = y; } } Bitmap bmp = new Bitmap(512, 512, System.Drawing.Imaging.PixelFormat.Format24bppRgb); for (int z = 0; z < 512; z++) { for (int x = 0; x < 512; x++) { int y = hm[x, z]; var block = r.GetBlock(x, y, z); if (block.IsAir && y > 0) { throw new ArgumentException("the mapped block was air."); } int shade = 0; if (mcMapShading && z > 0) { if (block.IsWater) { //Water dithering var depth = r.GetWaterDepth(x, y, z); if (depth < 8) { shade = 1; } else if (depth < 16) { shade = 0; } else { shade = -1; } if (depth % 8 >= 4 && shade > -1) { if (x % 2 == z % 2) { shade--; } } } else { int above = hm[x, z - 1]; if (above > y) { shade = -1; } else if (above < y) { shade = 1; } } } bmp.SetPixel(x, z, Blocks.GetMapColor(block, shade)); } } return(bmp); }
private void WriteHeightmapFromBlocks(short[,] hm, int localChunkX, int localChunkZ, HeightmapType type) { /*sbyte highestSection = 127; * while (highestSection > -127 && !sections.ContainsKey(highestSection)) * { * highestSection--; * } * if (highestSection == -127) return; * var sec = sections[highestSection]; */ for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { hm[localChunkX * 16 + x, localChunkZ * 16 + z] = GetHighestBlock(x, z, type); /* * short yTop; * if (hm[x, z] != 0) * { * //The heightmap is already present, proceed from provided y value * yTop = hm[x, z]; * } * else * { * yTop = (short)(highestSection * 16 + 15); * } * for (short y = yTop; y > 0; y--) * { * var block = sec.GetBlockAt(x, y % 16, z); * if (Blocks.IsBlockForMap(block.block, type)) * { * if (block.block.Compare("minecraft:snow")) * { * //Go down to grass level in case of a snow layer * y--; * } * hm[localChunkX * 16 + x, 511 - (localChunkZ * 16 + z)] = y; * break; * } * } */ } } }
private bool WriteHeightmapFromNBT(short[,] hm, int localChunkX, int localChunkZ, HeightmapType type) { if (sourceNBT == null) { return(false); } var chunkHM = sourceNBT.GetHeightmapFromChunkNBT(type); if (chunkHM == null) { return(false); } for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { hm[localChunkX * 16 + x, localChunkZ * 16 + z] = chunkHM[x, z]; } } return(true); }
private static void WriteChunkToHeightmap(short[,] heightmap, NBTContent nbt, int localChunkX, int localChunkZ, HeightmapType mapType) { //int chunkDataX = (int)nbt.contents.Get("xPos") - regionPos.x * 32; //int chunkDataZ = (int)nbt.contents.Get("zPos") - regionPos.z * 32; //var chunkHM = nbt.GetHeightmapFromChunkNBT(mapType); try { ChunkData chunk = new ChunkData(null, nbt); chunk.WriteToHeightmap(heightmap, localChunkX, localChunkZ, mapType); /*for (int x = 0; x < 16; x++) * { * for (int z = 0; z < 16; z++) * { * byte y = (chunkHM != null) ? (byte)Math.Max(chunkHM[x, z] - 1, 0) : (byte)255; * if (y > 1) * { * while (y > 0 && !Blocks.IsBlockForMap(chunk.GetBlockAt(x, y, z).block, mapType)) * { * y--; * } * } * heightmap[localChunkX * 16 + x, localChunkZ * 16 + z] = y; * } * } */ } catch { } }
/// <summary> /// Gets the highest block at the given location. /// </summary> public short GetHighestBlock(int x, int z, HeightmapType heightmapType) { return(GetRegionAt(x, z)?.GetHighestBlock(x % 512, z % 512, heightmapType) ?? short.MinValue); }