diff --git a/integrations/common/src/main/java/net/scopenet/worldmap/BlockColors.java b/integrations/common/src/main/java/net/scopenet/worldmap/BlockColors.java index 6aa7ce4..94d2f0a 100644 --- a/integrations/common/src/main/java/net/scopenet/worldmap/BlockColors.java +++ b/integrations/common/src/main/java/net/scopenet/worldmap/BlockColors.java @@ -35,13 +35,71 @@ public final class BlockColors { private static final int[] UNKNOWN = {STONE, DIRT, WOOD, GRAY, BROWN, LIGHT_GRAY, DEEPSLATE}; - /** 0 for blocks a map looks straight through (air, glass, rails, torches). */ + /** Water is special-cased by the renderer, which shades it by depth. */ + public static final int WATER_COLOR = 0xFF3F76E4; + + private static final Map TEXTURES = loadTextures(); + private static final Map COLORS = new ConcurrentHashMap<>(); + + /** + * The colour this block shows as on the map (opaque ARGB), or 0 for blocks a map looks straight through (air, glass, rails). + * Vanilla blocks use the average colour of their real top texture; anything without one falls back to the map colour table. + */ public static int of(String blockName) { + return COLORS.computeIfAbsent(blockName, BlockColors::resolve); + } + + /** The nearest vanilla map colour id for a block (0 = see-through); also what the fallback palette uses. */ + public static int mapColor(String blockName) { return CACHE.computeIfAbsent(blockName, BlockColors::classify); } + private static int resolve(String full) { + int id = mapColor(full); + if (id == 0) return 0; + if (id == WATER) return WATER_COLOR; + String n = plain(full); + Integer exact = TEXTURES.get(n); + if (exact != null) return exact; + String s = n; + for (boolean changed = true; changed; ) { + changed = false; + for (String p : STRIP_PREFIX) if (s.startsWith(p) && s.length() > p.length()) { s = s.substring(p.length()); changed = true; } + for (String p : STRIP_SUFFIX) if (s.endsWith(p) && s.length() > p.length()) { s = s.substring(0, s.length() - p.length()); changed = true; } + if (!changed) break; + for (String candidate : new String[]{s, s + "s", s + "_planks", s + "_block"}) { + Integer hit = TEXTURES.get(candidate); + if (hit != null) return hit; + } + } + return MapColors.base(id); + } + + private static String plain(String full) { + return full.startsWith("minecraft:") ? full.substring(10) : full.substring(full.indexOf(':') + 1); + } + + private static Map loadTextures() { + Map out = new java.util.HashMap<>(); + try (java.io.InputStream in = BlockColors.class.getResourceAsStream("block_colors.csv")) { + if (in == null) return out; + for (String line : new String(in.readAllBytes(), java.nio.charset.StandardCharsets.UTF_8).split("\n")) { + int comma = line.indexOf(','); + if (comma <= 0 || comma + 7 > line.length()) continue; + try { + out.put(line.substring(0, comma), 0xFF000000 | Integer.parseInt(line.substring(comma + 1, comma + 7).trim(), 16)); + } catch (NumberFormatException ignored) { + // a malformed row just falls back to the map colour table + } + } + } catch (java.io.IOException ignored) { + // no texture table: the map colour table covers everything + } + return out; + } + private static int classify(String full) { - String n = full.startsWith("minecraft:") ? full.substring(10) : full.substring(full.indexOf(':') + 1); + String n = plain(full); int c = lookup(n); if (c >= 0) return c; // Peel shape and finish words (cut_sandstone_stairs -> sandstone) and try again. @@ -150,5 +208,5 @@ public final class BlockColors { return -1; } - public static boolean isWater(int colour) { return colour == WATER; } + public static boolean isWater(int colour) { return colour == WATER_COLOR; } } diff --git a/integrations/common/src/main/java/net/scopenet/worldmap/ChunkSampler.java b/integrations/common/src/main/java/net/scopenet/worldmap/ChunkSampler.java index 40f6411..bf14884 100644 --- a/integrations/common/src/main/java/net/scopenet/worldmap/ChunkSampler.java +++ b/integrations/common/src/main/java/net/scopenet/worldmap/ChunkSampler.java @@ -82,7 +82,7 @@ public final class ChunkSampler { if (c == 0) continue; out.color[i] = c; out.height[i] = worldY; - if (c == MapColors.WATER) out.depth[i] = waterDepth(sections, si, ly, x, z); + if (c == BlockColors.WATER_COLOR) out.depth[i] = waterDepth(sections, si, ly, x, z); return; } } @@ -97,7 +97,7 @@ public final class ChunkSampler { for (int s = si; s < sections.size(); s++) { Section sec = sections.get(s); for (int y = s == si ? ly - 1 : 15; y >= 0; y--) { - if (sec.colorAt(x, y, z) != MapColors.WATER) return depth; + if (sec.colorAt(x, y, z) != BlockColors.WATER_COLOR) return depth; if (++depth >= 64) return depth; } } diff --git a/integrations/common/src/main/java/net/scopenet/worldmap/MapColors.java b/integrations/common/src/main/java/net/scopenet/worldmap/MapColors.java index 66f9e1a..e64d9a2 100644 --- a/integrations/common/src/main/java/net/scopenet/worldmap/MapColors.java +++ b/integrations/common/src/main/java/net/scopenet/worldmap/MapColors.java @@ -25,6 +25,9 @@ public final class MapColors { /** Brightness factors for the four shades: darkest .. brightest, as a map shows low, normal, high and lowest ground. */ private static final int[] SHADE = {180, 220, 255, 135}; + /** The colour's base RGB (opaque ARGB), or 0 for none. */ + public static int base(int id) { return id <= 0 || id >= COUNT ? 0 : 0xFF000000 | RGB[id]; } + /** Opaque ARGB for a colour id at a shade (0 = low, 1 = normal, 2 = high, 3 = lowest); 0 for no colour. */ public static int argb(int id, int shade) { if (id <= 0 || id >= COUNT) return 0; diff --git a/integrations/common/src/main/java/net/scopenet/worldmap/Png.java b/integrations/common/src/main/java/net/scopenet/worldmap/Png.java index 4f463e6..b9cb7b9 100644 --- a/integrations/common/src/main/java/net/scopenet/worldmap/Png.java +++ b/integrations/common/src/main/java/net/scopenet/worldmap/Png.java @@ -3,6 +3,9 @@ package net.scopenet.worldmap; import java.io.ByteArrayOutputStream; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -18,6 +21,7 @@ public final class Png { * that fits (a typical tile is a few KB instead of tens); anything with more than 256 colours falls back to RGBA. */ public static byte[] encode(int[] argb, int width, int height) { + argb = limitColors(argb); Map palette = new LinkedHashMap<>(); for (int c : argb) { int key = (c >>> 24) == 0 ? 0 : c; @@ -65,6 +69,36 @@ public final class Png { return out.toByteArray(); } + /** + * Keeps a tile within 256 colours: when it has more, the rarest colours are snapped to the nearest common one. Tiles + * rarely get there (blocks have few colours and shading adds only a handful of steps), and the change is hard to see. + */ + static int[] limitColors(int[] argb) { + Map counts = new HashMap<>(); + for (int c : argb) if ((c >>> 24) != 0) counts.merge(c, 1, Integer::sum); + if (counts.size() <= 255) return argb; + List keep = new ArrayList<>(counts.keySet()); + keep.sort((a, b) -> counts.get(b) - counts.get(a)); + List top = new ArrayList<>(keep.subList(0, 255)); + Set kept = new HashSet<>(top); + Map remap = new HashMap<>(); + int[] out = argb.clone(); + for (int i = 0; i < out.length; i++) { + int c = out[i]; + if ((c >>> 24) == 0 || kept.contains(c)) continue; + out[i] = remap.computeIfAbsent(c, k -> { + int best = top.get(0), bestD = Integer.MAX_VALUE; + for (int q : top) { + int dr = (k >> 16 & 0xFF) - (q >> 16 & 0xFF), dg = (k >> 8 & 0xFF) - (q >> 8 & 0xFF), db = (k & 0xFF) - (q & 0xFF); + int d = dr * dr * 2 + dg * dg * 4 + db * db * 3; + if (d < bestD) { bestD = d; best = q; } + } + return best; + }); + } + return out; + } + private static final byte[] SIGNATURE = {(byte) 0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n'}; private static byte[] deflate(byte[] raw) { diff --git a/integrations/common/src/main/java/net/scopenet/worldmap/RegionRenderer.java b/integrations/common/src/main/java/net/scopenet/worldmap/RegionRenderer.java index b9fdbca..93cb354 100644 --- a/integrations/common/src/main/java/net/scopenet/worldmap/RegionRenderer.java +++ b/integrations/common/src/main/java/net/scopenet/worldmap/RegionRenderer.java @@ -47,7 +47,10 @@ public final class RegionRenderer { return tiles; } - /** Shading as a vanilla map does it: slope against the block to the north, depth for water, plus a light dither. */ + /** + * Shading: ground is lit by its slope against the block to the north (a gentle relief effect), water darkens with depth. + * Colours are the blocks' own, so they stay in few steps and compress well. + */ static int[] shade(int[] colors, int[] heights, int[] depths) { int[] out = new int[SIDE * SIDE]; for (int z = 0; z < SIDE; z++) { @@ -55,18 +58,23 @@ public final class RegionRenderer { int i = z * SIDE + x; int c = colors[i]; if (c == 0) continue; - int shade; - if (c == MapColors.WATER) { - double d = depths[i] * 0.1 + ((x + z) & 1) * 0.2; - shade = d < 0.5 ? 2 : d > 0.9 ? 0 : 1; + int percent; + if (c == BlockColors.WATER_COLOR) { + percent = 108 - Math.min(depths[i], 14) * 4; } else { int north = z > 0 && colors[i - SIDE] != 0 ? heights[i - SIDE] : heights[i]; - double d = (heights[i] - north) * 4.0 / 5.0 + (((x + z) & 1) - 0.5) * 0.4; - shade = d > 0.6 ? 2 : d < -0.6 ? 0 : 1; + int diff = heights[i] - north; + percent = diff >= 2 ? 120 : diff == 1 ? 109 : diff == 0 ? 100 : diff == -1 ? 90 : 80; } - out[i] = MapColors.argb(c, shade); + out[i] = scale(c, percent); } } return out; } + + static int scale(int argb, int percent) { + int r = Math.min(255, (argb >> 16 & 0xFF) * percent / 100), g = Math.min(255, (argb >> 8 & 0xFF) * percent / 100), + b = Math.min(255, (argb & 0xFF) * percent / 100); + return 0xFF000000 | r << 16 | g << 8 | b; + } } diff --git a/integrations/common/src/main/resources/net/scopenet/worldmap/block_colors.csv b/integrations/common/src/main/resources/net/scopenet/worldmap/block_colors.csv new file mode 100644 index 0000000..b94985c --- /dev/null +++ b/integrations/common/src/main/resources/net/scopenet/worldmap/block_colors.csv @@ -0,0 +1,418 @@ +stone,989898 +granite,B6775E +polished_granite,BC7A63 +diorite,E5E5E5 +polished_diorite,EAEBED +andesite,A6A6A6 +polished_andesite,A1A3A2 +grass_block,618149 +dirt,A37048 +coarse_dirt,91633F +podzol,6F4913 +cobblestone,9B9B9B +oak_planks,C69A53 +spruce_planks,8B6231 +birch_planks,EAD389 +jungle_planks,C38656 +acacia_planks,CD622C +cherry_planks,FFC2BB +dark_oak_planks,513112 +mangrove_planks,8F3930 +bamboo_planks,EBD051 +bamboo_mosaic,E8CC4F +bedrock,686868 +sand,FFEFB6 +red_sand,E87011 +gravel,A09A99 +gold_ore,B1A17C +deepslate_gold_ore,8C7B5A +iron_ore,A69C93 +deepslate_iron_ore,817871 +coal_ore,808080 +deepslate_coal_ore,5A5A5D +nether_gold_ore,8C3929 +oak_log,B88F4E +spruce_log,845E2F +birch_log,EBD89C +jungle_log,B67F4A +acacia_log,B76235 +cherry_log,E2A6A0 +dark_oak_log,523414 +mangrove_log,7C332A +mangrove_roots,5A4629 +muddy_mangrove_roots,554533 +bamboo_block,A9AC40 +stripped_spruce_log,805E2F +stripped_birch_log,E9CE83 +stripped_jungle_log,C98F57 +stripped_acacia_log,CB642D +stripped_cherry_log,FFB5AC +stripped_dark_oak_log,4F3315 +stripped_oak_log,C39952 +stripped_mangrove_log,852B2B +stripped_bamboo_block,D9BE48 +oak_leaves,4D7515 +spruce_leaves,355C35 +jungle_leaves,557E14 +cherry_leaves,FFB8D3 +dark_oak_leaves,517B16 +mangrove_leaves,456913 +azalea_leaves,6A8B2B +flowering_azalea_leaves,778742 +sponge,EEEA49 +wet_sponge,CFDD45 +lapis_ore,7E8BAC +deepslate_lapis_ore,5B6A8C +lapis_block,1447AB +dispenser,959393 +sandstone,FFF3BB +chiseled_sandstone,FFECAE +cut_sandstone,FFF1B3 +note_block,6B422A +powered_rail,A78151 +detector_rail,967C69 +piston,BB975E +white_wool,FBFFFF +orange_wool,FF7200 +magenta_wool,E741D9 +light_blue_wool,2EC8FF +yellow_wool,FFC40E +lime_wool,7EE207 +pink_wool,FF8BB1 +gray_wool,4A5357 +light_gray_wool,ADADA2 +cyan_wool,07A6B1 +purple_wool,8C20D2 +blue_wool,3137C0 +brown_wool,8B5026 +green_wool,638515 +red_wool,C31E17 +black_wool,18191E +gold_block,FFD328 +iron_block,FFFFFF +bricks,B76F5B +tnt,AD4034 +bookshelf,8F6F3F +chiseled_bookshelf,D9AB5E +mossy_cobblestone,85906F +obsidian,110A1D +spawner,28364C +diamond_ore,91ACAB +deepslate_diamond_ore,628181 +diamond_block,57FFF4 +crafting_table,915228 +farmland,AE764B +furnace,868585 +oak_door,AB8246 +iron_door,EDEBEB +redstone_ore,AB8080 +deepslate_redstone_ore,7F5556 +snow,F9FFFF +ice,85B0FF +cactus,629B28 +clay,C0C9DA +jukebox,714A33 +netherrack,762626 +soul_sand,634938 +soul_soil,5C4334 +basalt,616269 +polished_basalt,79777A +glowstone,D19A5A +nether_portal,6400EA +carved_pumpkin,B75D01 +jack_o_lantern,FFAC27 +cake,FFE1D8 +repeater,C3BFBE +oak_trapdoor,97753A +spruce_trapdoor,7E5D31 +birch_trapdoor,FDEBB8 +jungle_trapdoor,B98053 +acacia_trapdoor,BE602F +cherry_trapdoor,FFC2BB +dark_oak_trapdoor,5C3814 +mangrove_trapdoor,862F29 +bamboo_trapdoor,F2D857 +stone_bricks,959395 +mossy_stone_bricks,8B947E +cracked_stone_bricks,908F90 +chiseled_stone_bricks,919091 +packed_mud,AD7C57 +mud_bricks,A77958 +brown_mushroom_block,B68259 +red_mushroom_block,F42220 +mushroom_stem,F8EEDF +pumpkin,F28404 +melon,83B014 +mycelium,87767A +nether_bricks,36161D +enchanting_table,9C5461 +cauldron,59585A +end_portal_frame,6B9273 +end_stone,FBFFAD +dragon_egg,0E0A12 +redstone_lamp,743C1B +emerald_ore,80A689 +deepslate_emerald_ore,5B7F68 +emerald_block,1CF859 +command_block,D89C78 +beacon,79FFF9 +anvil,585858 +chipped_anvil,585858 +damaged_anvil,585858 +comparator,CBC4C1 +daylight_detector,9F8B6D +redstone_block,D61800 +nether_quartz_ore,8F4844 +hopper,5C5A5C +quartz_block,FFF8EF +chiseled_quartz_block,FFF9EE +quartz_pillar,FFF8EF +activator_rail,8C6654 +dropper,959393 +white_terracotta,FFD5BD +orange_terracotta,C45A1B +magenta_terracotta,B6627E +light_blue_terracotta,8680A7 +yellow_terracotta,E39B15 +lime_terracotta,7C8F36 +pink_terracotta,C45353 +gray_terracotta,463127 +light_gray_terracotta,A57D71 +cyan_terracotta,686F6F +purple_terracotta,904E64 +blue_terracotta,58436F +brown_terracotta,5E3A25 +green_terracotta,5C652D +red_terracotta,AE3E2A +black_terracotta,2D1910 +slime_block,7CEA60 +iron_trapdoor,F6F6F6 +prismarine,6EC6AE +prismarine_bricks,6ED1BF +dark_prismarine,386F59 +sea_lantern,CEF4E6 +hay_block,C9A700 +terracotta,B96A45 +coal_block,141212 +packed_ice,82AFFF +red_sandstone,DD6A10 +chiseled_red_sandstone,DF680A +cut_red_sandstone,E76E0F +smooth_stone_slab,CCCCCC +smooth_stone,C1C1C1 +bamboo_fence_gate,FBDF57 +bamboo_fence,FBE05B +spruce_door,815E32 +birch_door,FFF1C6 +jungle_door,C78B5B +acacia_door,CC693A +cherry_door,FFBBB3 +dark_oak_door,5D3B17 +mangrove_door,89312E +bamboo_door,E9CE53 +chorus_plant,714071 +chorus_flower,B88EB8 +purpur_block,CE92CE +purpur_pillar,D196D1 +end_stone_bricks,F7FFB0 +dirt_path,B59043 +repeating_command_block,967DCF +chain_command_block,9BC4B1 +nether_wart_block,8B0000 +red_nether_bricks,540003 +bone_block,FFFBD6 +observer,787878 +shulker_box,AA6FAA +white_shulker_box,F7FEFF +orange_shulker_box,FF6F00 +magenta_shulker_box,D330C5 +light_blue_shulker_box,23BDFF +yellow_shulker_box,FFBA03 +lime_shulker_box,6ED206 +pink_shulker_box,FF78A4 +gray_shulker_box,42464C +light_gray_shulker_box,97978B +cyan_shulker_box,0892A5 +purple_shulker_box,7615BE +blue_shulker_box,2629AB +brown_shulker_box,814B20 +green_shulker_box,5D7A1C +red_shulker_box,AB1614 +black_shulker_box,1E1E23 +white_glazed_terracotta,DFFFF2 +orange_glazed_terracotta,BCB266 +magenta_glazed_terracotta,FE6AE7 +light_blue_glazed_terracotta,62C2FE +yellow_glazed_terracotta,FFCC4D +lime_glazed_terracotta,C1F02E +pink_glazed_terracotta,FF9DBD +gray_glazed_terracotta,646D71 +light_gray_glazed_terracotta,ACCACC +cyan_glazed_terracotta,358F98 +purple_glazed_terracotta,7F2AB9 +blue_glazed_terracotta,2C43AA +brown_glazed_terracotta,917F63 +green_glazed_terracotta,8BAD47 +red_glazed_terracotta,DD362E +black_glazed_terracotta,521F22 +white_concrete,F6FEFF +orange_concrete,FF6E00 +magenta_concrete,CE29C1 +light_blue_concrete,139EF2 +yellow_concrete,FFB300 +lime_concrete,68CD08 +pink_concrete,FF69A0 +gray_concrete,41454A +light_gray_concrete,98988B +cyan_concrete,098FA6 +purple_concrete,7214BE +blue_concrete,272AAE +brown_concrete,75431C +green_concrete,566F24 +red_concrete,AD1717 +black_concrete,090B12 +white_concrete_powder,FCFFFF +orange_concrete_powder,FF8608 +magenta_concrete_powder,EA55DF +light_blue_concrete_powder,45D3FF +yellow_concrete_powder,FFD624 +lime_concrete_powder,8FE71C +pink_concrete_powder,FFA1C4 +gray_concrete_powder,5C6266 +light_gray_concrete_powder,BCBCB4 +cyan_concrete_powder,1AB2C0 +purple_concrete_powder,9931D8 +blue_concrete_powder,474BCB +brown_concrete_powder,986036 +green_concrete_powder,73912B +red_concrete_powder,CD312C +black_concrete_powder,1E1F26 +dead_tube_coral_block,9F9590 +dead_brain_coral_block,978E8A +dead_bubble_coral_block,A0958F +dead_fire_coral_block,A0958F +dead_horn_coral_block,A29993 +tube_coral_block,2559FB +brain_coral_block,FD5EBB +bubble_coral_block,C90BC5 +fire_coral_block,C71827 +horn_coral_block,FFE939 +sea_pickle,6D7627 +blue_ice,649EFF +bamboo,EBD051 +scaffolding,CF9A4B +loom,AD8E68 +barrel,A3753C +smoker,686562 +blast_furnace,616163 +cartography_table,7E684C +fletching_table,F0D999 +lectern,D3A258 +smithing_table,444555 +stonecutter,968F86 +warped_stem,388586 +stripped_warped_stem,349C97 +warped_nylium,2A8B79 +warped_wart_block,0C9194 +crimson_stem,89334F +stripped_crimson_stem,943B5E +crimson_nylium,9F1717 +shroomlight,FF8F35 +crimson_planks,7B3351 +warped_planks,2C7F78 +crimson_trapdoor,7E3553 +warped_trapdoor,2F9186 +crimson_door,8B395B +warped_door,2A9A92 +structure_block,6B586E +jigsaw,615263 +target,FFB8A8 +bee_nest,F6BD48 +beehive,C0954F +honey_block,FFB41D +honeycomb_block,FF9A06 +netherite_block,514A4C +ancient_debris,734C41 +crying_obsidian,230549 +respawn_anchor,520BB6 +lodestone,B3B5B9 +blackstone,332B32 +polished_blackstone,403944 +polished_blackstone_bricks,3A323C +cracked_polished_blackstone_bricks,362C34 +chiseled_polished_blackstone,403944 +gilded_blackstone,43312C +chiseled_nether_bricks,39191F +cracked_nether_bricks,31151A +quartz_bricks,FFF9EF +amethyst_block,9A69E9 +budding_amethyst,9968E3 +tuff,84857B +polished_tuff,757F78 +chiseled_tuff,71786E +tuff_bricks,777C73 +chiseled_tuff_bricks,868A80 +calcite,FEFFFA +powder_snow,F9FFFF +sculk_sensor,005466 +calibrated_sculk_sensor,165D7A +sculk,0D2028 +sculk_vein,013A47 +sculk_catalyst,0F252E +copper_block,EA7650 +exposed_copper,C49375 +weathered_copper,7DBB80 +oxidized_copper,58C69D +copper_ore,979892 +deepslate_copper_ore,70716C +oxidized_cut_copper,56BB96 +weathered_cut_copper,80B17D +exposed_cut_copper,BC8F73 +cut_copper,E97551 +oxidized_chiseled_copper,5AC49D +weathered_chiseled_copper,78B782 +exposed_chiseled_copper,BC8C72 +chiseled_copper,E06E49 +copper_door,EA7954 +exposed_copper_door,C89079 +oxidized_copper_door,59C39D +weathered_copper_door,80B77F +copper_trapdoor,E87550 +exposed_copper_trapdoor,C49377 +oxidized_copper_trapdoor,5AC49D +weathered_copper_trapdoor,7DBB80 +copper_grate,E97650 +exposed_copper_grate,C49377 +weathered_copper_grate,7BB980 +oxidized_copper_grate,58C49B +copper_bulb,BE5F37 +exposed_copper_bulb,A57E66 +weathered_copper_bulb,6B9A75 +oxidized_copper_bulb,4CA182 +dripstone_block,A37F6A +azalea,78972E +flowering_azalea,879446 +moss_block,6A852E +big_dripleaf,83AC31 +rooted_dirt,B07853 +mud,494549 +deepslate,6A6A6D +cobbled_deepslate,5E5E62 +polished_deepslate,585859 +deepslate_tiles,424243 +deepslate_bricks,555557 +chiseled_deepslate,424242 +cracked_deepslate_bricks,4E4E4F +cracked_deepslate_tiles,3F3F3F +smooth_basalt,57575F +raw_iron_block,CBA07A +raw_copper_block,BC7955 +raw_gold_block,FFBC1D +ochre_froglight,FFF9CD +verdant_froglight,EDFFEC +pearlescent_froglight,FFF9F8 +reinforced_deepslate,61645F +crafter,897677 +trial_spawner,2D455D +vault,3E5360 +heavy_core,626873 diff --git a/integrations/common/src/test/java/net/scopenet/worldmap/MapRenderTest.java b/integrations/common/src/test/java/net/scopenet/worldmap/MapRenderTest.java index 06c45b7..eb2669f 100644 --- a/integrations/common/src/test/java/net/scopenet/worldmap/MapRenderTest.java +++ b/integrations/common/src/test/java/net/scopenet/worldmap/MapRenderTest.java @@ -86,23 +86,29 @@ class MapRenderTest { } @Test void blockNamesBecomeMapColours() { - assertEquals(MapColors.NONE, BlockColors.of("minecraft:air")); - assertEquals(MapColors.NONE, BlockColors.of("minecraft:glass")); - assertEquals(MapColors.GRASS, BlockColors.of("minecraft:grass_block")); - assertEquals(MapColors.WATER, BlockColors.of("minecraft:water")); - assertEquals(MapColors.STONE, BlockColors.of("minecraft:stone")); - assertEquals(MapColors.STONE, BlockColors.of("minecraft:mossy_cobblestone_stairs")); - assertEquals(MapColors.WOOD, BlockColors.of("minecraft:oak_planks")); - assertEquals(MapColors.WOOD, BlockColors.of("minecraft:oak_stairs")); - assertEquals(MapColors.PLANT, BlockColors.of("minecraft:oak_leaves")); - assertEquals(MapColors.SAND, BlockColors.of("minecraft:cut_sandstone_slab")); - assertEquals(MapColors.NETHER, BlockColors.of("minecraft:netherrack")); - assertEquals(MapColors.RED, BlockColors.of("minecraft:red_wool") == MapColors.RED ? MapColors.RED : -1); - assertEquals(MapColors.LIGHT_BLUE, BlockColors.of("minecraft:light_blue_concrete")); - assertEquals(MapColors.DEEPSLATE, BlockColors.of("minecraft:deepslate_iron_ore")); - assertEquals(MapColors.FIRE, BlockColors.of("minecraft:lava")); - int modded = BlockColors.of("create:brass_casing"); - assertEquals(modded, BlockColors.of("create:brass_casing"), "stable for unknown blocks"); + assertEquals(MapColors.NONE, BlockColors.mapColor("minecraft:air")); + assertEquals(MapColors.NONE, BlockColors.mapColor("minecraft:glass")); + assertEquals(MapColors.GRASS, BlockColors.mapColor("minecraft:grass_block")); + assertEquals(MapColors.WATER, BlockColors.mapColor("minecraft:water")); + assertEquals(MapColors.STONE, BlockColors.mapColor("minecraft:stone")); + assertEquals(MapColors.STONE, BlockColors.mapColor("minecraft:mossy_cobblestone_stairs")); + assertEquals(MapColors.WOOD, BlockColors.mapColor("minecraft:oak_planks")); + assertEquals(MapColors.WOOD, BlockColors.mapColor("minecraft:oak_stairs")); + assertEquals(MapColors.PLANT, BlockColors.mapColor("minecraft:oak_leaves")); + assertEquals(MapColors.SAND, BlockColors.mapColor("minecraft:cut_sandstone_slab")); + assertEquals(MapColors.NETHER, BlockColors.mapColor("minecraft:netherrack")); + assertEquals(MapColors.RED, BlockColors.mapColor("minecraft:red_wool") == MapColors.RED ? MapColors.RED : -1); + assertEquals(MapColors.LIGHT_BLUE, BlockColors.mapColor("minecraft:light_blue_concrete")); + assertEquals(MapColors.DEEPSLATE, BlockColors.mapColor("minecraft:deepslate_iron_ore")); + assertEquals(MapColors.FIRE, BlockColors.mapColor("minecraft:lava")); + assertEquals(0, BlockColors.of("minecraft:air")); + assertEquals(BlockColors.WATER_COLOR, BlockColors.of("minecraft:water")); + int grass = BlockColors.of("minecraft:grass_block"); + assertTrue((grass >> 8 & 0xFF) > (grass >> 16 & 0xFF) && (grass >> 8 & 0xFF) > (grass & 0xFF), "grass is green"); + assertEquals(BlockColors.of("minecraft:oak_planks"), BlockColors.of("minecraft:oak_stairs"), "shapes share their material's colour"); + assertTrue(BlockColors.of("create:brass_casing") != 0, "modded blocks still get a colour"); + int modded = BlockColors.mapColor("create:brass_casing"); + assertEquals(modded, BlockColors.mapColor("create:brass_casing"), "stable for unknown blocks"); assertTrue(modded > 0); } @@ -128,9 +134,9 @@ class MapRenderTest { try (var in = new DataInputStream(new ByteArrayInputStream(nbt))) { c = Nbt.readRoot(in); } ChunkSampler.Columns cols = new ChunkSampler.Columns(); assertTrue(ChunkSampler.sample(c, ChunkSampler.Kind.OVERWORLD, cols)); - assertEquals(MapColors.STONE, cols.color[15]); + assertEquals(BlockColors.of("minecraft:stone"), cols.color[15]); assertEquals(4 * 16 + 5, cols.height[15]); - assertEquals(MapColors.WATER, cols.color[0]); + assertEquals(BlockColors.WATER_COLOR, cols.color[0]); assertEquals(4 * 16 + 8, cols.height[0]); assertEquals(3, cols.depth[0]); } @@ -143,7 +149,7 @@ class MapRenderTest { try (var in = new DataInputStream(new ByteArrayInputStream(nbt))) { c = Nbt.readRoot(in); } ChunkSampler.Columns cols = new ChunkSampler.Columns(); assertTrue(ChunkSampler.sample(c, ChunkSampler.Kind.NETHER, cols)); - assertEquals(MapColors.NETHER, cols.color[0], "the floor, not the bedrock roof"); + assertEquals(BlockColors.of("minecraft:netherrack"), cols.color[0], "the floor, not the bedrock roof"); assertEquals(7 * 16 + 3, cols.height[0]); } @@ -165,7 +171,7 @@ class MapRenderTest { @Test void slopesAreShadedAgainstTheNorth() { int n = 512; int[] colors = new int[n * n], heights = new int[n * n], depths = new int[n * n]; - Arrays.fill(colors, MapColors.STONE); + Arrays.fill(colors, BlockColors.of("minecraft:stone")); for (int z = 0; z < n; z++) Arrays.fill(heights, z * n, z * n + n, 64 + z / 8 * 3); int[] px = RegionRenderer.shade(colors, heights, depths); int uphill = px[16 * n + 3]; // a step up from the north