/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.pepsoft.worldpainter.colourschemes; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Arrays; import org.jetbrains.annotations.NonNls; import org.pepsoft.minecraft.Material; import org.pepsoft.worldpainter.ColourScheme; /** * An implementation of {@link ColourScheme} which can read * <a href="http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/1286593-dynmap-dynamic-web-based-maps-for-minecraft">Dynmap</a> * "classic" colour scheme files, such as those included with Dynmap. * * @author pepijn */ public final class DynMapColourScheme implements ColourScheme { /** * Create a new Dynmap colour scheme, reading the Dynamp "classic" colour scheme-formatted colour map from an input * stream. * * @param in The input stream from which to read the colours. * @param bright Whether to use the brightest colours. When <code>false</code> the two block side colours are * averaged and used instead. The brightest colours usually most approximate the colours as * experienced in Minecraft, so when in doubt, use <code>true</code>. */ public DynMapColourScheme(InputStream in, boolean bright) { loadColours(in, bright); } /** * Create a new Dynmap colour scheme, reading the Dynamp "classic" colour scheme-formatted colour map from a file * on the classpath. The file should be named <code><em>name</em>.txt</code> and be in the * <code>org.pepsoft.worldpainter.colourschemes</code> package. * * @param name The name of the Dynmap "classic" colour map file to read from the classpath, without * <code>.txt</code> extension. * @param bright Whether to use the brightest colours. When <code>false</code> the two block side colours are * averaged and used instead. The brightest colours usually most approximate the colours as * experienced in Minecraft, so when in doubt, use <code>true</code>. */ public DynMapColourScheme(@NonNls String name, boolean bright) { loadColours(DynMapColourScheme.class.getResourceAsStream(name + ".txt"), bright); } @Override public int getColour(int blockType) { return (blockType < 256) ? COLOURS[blockType] : UNKNOWN_BLOCK_TYPE_COLOUR; } @Override public int getColour(int blockType, int dataValue) { return (blockType < 256) ? COLOURS[blockType + dataValue * 256] : UNKNOWN_BLOCK_TYPE_COLOUR; } @Override public int getColour(Material material) { final int blockType = material.blockType; return (blockType < 256) ? COLOURS[blockType + material.data * 256] : UNKNOWN_BLOCK_TYPE_COLOUR; } private void loadColours(InputStream in, boolean bright) { // Make all unknown blocks cyan instead of black Arrays.fill(COLOURS, UNKNOWN_BLOCK_TYPE_COLOUR); try { try { BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line; while ((line = reader.readLine()) != null) { line = line.trim(); // Skip comments, empty lines, and non-block type colours if ((line.length() == 0) || line.startsWith("#") || line.startsWith("[")) { continue; } // Skip lines without enough tokens String[] tokens = line.split("\\s+"); if (tokens.length < 17) { continue; } // Decode block ID and data value (if any) int p = tokens[0].indexOf(':'); int blockID, dataValue; if (p != -1) { // Data value-specific colour blockID = Integer.parseInt(tokens[0].substring(0, p)); dataValue = Integer.parseInt(tokens[0].substring(p + 1)); } else { // Non-data value-specific colour blockID = Integer.parseInt(tokens[0]); dataValue = -1; } // Decode colour int[] colourComponents = new int[16]; for (int i = 0; i < 16; i++) { colourComponents[i] = Integer.parseInt(tokens[i + 1]); } // R G B A // 0 1 2 3 0 // 4 5 6 7 3 // 8 9 10 11 1 // 12 13 14 15 2 int red, green, blue; if (bright) { red = colourComponents[0]; green = colourComponents[1]; blue = colourComponents[2]; } else { red = (colourComponents[ 8] + colourComponents[4]) / 2; green = (colourComponents[ 9] + colourComponents[5]) / 2; blue = (colourComponents[10] + colourComponents[6]) / 2; } int colour = (red << 16) | (green << 8) | blue; // Store the colour if (dataValue == -1) { for (int i = 0; i < 16; i++) { COLOURS[blockID + i * 256] = colour; } } else { COLOURS[blockID + dataValue * 256] = colour; } } } finally { in.close(); } } catch (IOException e) { throw new RuntimeException("I/O error reading colour scheme", e); } } private final int COLOURS[] = new int[256 * 16]; private static final int UNKNOWN_BLOCK_TYPE_COLOUR = 0x00ffff; // Cyan }