diff --git a/src/main/java/baritone/map/MapChunk.java b/src/main/java/baritone/map/MapChunk.java index 54287525..a3ab048b 100644 --- a/src/main/java/baritone/map/MapChunk.java +++ b/src/main/java/baritone/map/MapChunk.java @@ -4,7 +4,9 @@ import baritone.bot.Baritone; import baritone.bot.utils.BlockStateInterface; import baritone.bot.utils.pathing.BetterBlockPos; import net.minecraft.block.material.MapColor; +import net.minecraft.init.Blocks; import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos.MutableBlockPos; import net.minecraft.world.chunk.Chunk; import org.lwjgl.util.Color; @@ -52,21 +54,45 @@ public class MapChunk { return new File(new File(Baritone.INSTANCE.getDir(), "map"), "chunk" + chunk.x + "-" + chunk.z + ".png").toPath(); } + /** + * getColor is a re-implementation of the Minecraft ItemMap's + * surface mapping system. This is significantly less convoluted + * than the poorly de-obfuscated code. + * + * We perform shading of the given coordinate relative to the + * position one to the north of the coordinate, as can be seen + * in Minecraft's maps. + * + * @param x relative x coordinate to the start of the chunk + * @param z relative z coord. + * @return Integer RGB value with contextual shading + */ public int getColor(int x, int z) { int chunkX = chunk.getPos().getXStart() + x; int chunkZ = chunk.getPos().getZStart() + z; MutableBlockPos blockPos = new MutableBlockPos(chunkX, chunk.getHeight(new BetterBlockPos(chunkX, 0, chunkZ)), chunkZ); MapColor color = BlockStateInterface.get(blockPos).getMapColor(chunk.getWorld(), blockPos); - int colorValue = color != MapColor.AIR ? color.colorValue : BlockStateInterface.get(blockPos.move(EnumFacing.DOWN)).getMapColor(chunk.getWorld(), blockPos).colorValue; + + // The chunk heightMap returns the first non-full block above the surface, including bushes. + // We have to check this and shift our block down by one if the color is "air" (as in, there's no real block there) + int colorValue = color != MapColor.AIR ? color.colorValue : BlockStateInterface.get(blockPos.down()).getMapColor(chunk.getWorld(), blockPos).colorValue; int red = (colorValue >> 16) & 0xFF; int green = (colorValue >> 8) & 0xFF; int blue = colorValue & 0xFF; - float heightCoef = (((float) blockPos.getY()) / 255) + 0.5f; - colorValue = (int) (red * heightCoef); - colorValue = (colorValue << 8) + (int) (green * heightCoef); - colorValue = (colorValue << 8) + (int) (blue * heightCoef); - return colorValue; + // Now we get the proper block for the position one to the north. + BlockPos offset = blockPos.offset(EnumFacing.NORTH); + offset = new BlockPos(offset.getX(), chunk.getHeight(offset), offset.getZ()); + // And once again, check to make sure we have an actual colored block an not "air" + if(BlockStateInterface.get(offset).getMapColor(chunk.getWorld(), offset) == MapColor.AIR) + offset = offset.down(); + + // We start the heightCoef at 0.8 to darken the colors similar to vanilla Minecraft's. + float heightCoef = 0.8f + (Math.signum(blockPos.getY() - offset.getY()) * 0.2f); + int newColor = Math.min(255, (int) (red * heightCoef)); + newColor = (newColor << 8) + Math.min(255, (int) (green * heightCoef)); + newColor = (newColor << 8) + Math.min(255, (int) (blue * heightCoef)); + return newColor; } }