blob: 49e7ed4599799848455be37d898f5e7b1997dd47 [file] [log] [blame] [raw]
/**
* Copyright (c) 2010-2011, Vincent Vollers and Christopher J. Kucera
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Minecraft X-Ray team nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL VINCENT VOLLERS OR CJ KUCERA BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.apocalyptech.minecraft.xray;
import com.apocalyptech.minecraft.xray.dialog.ExceptionDialog;
import java.awt.Color;
import java.awt.Font;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.lang.Integer;
import java.io.InputStream;
import java.io.IOException;
import org.lwjgl.input.Keyboard;
/***
* Precalcs and the like
* @author Vincent
*/
public class MinecraftConstants {
// translation table (precalc) from sprite sheet index to texture coordinates
public static float[] precalcSpriteSheetToTextureX;
public static float[] precalcSpriteSheetToTextureY;
public static final float TEX16 = 1.0f/16.0f;
public static final float TEX32 = 1.0f/32.0f;
public static final float TEX64 = 1.0f/64.0f;
public static final float TEX128 = 1.0f/128.0f;
public static final float TEX256 = 1.0f/256.0f;
public static final float TEX512 = 1.0f/512.0f;
public static final int BLOCKSPERROW = 128;
public static final int BLOCKSPERCOLUMN = BLOCKSPERROW * 16;
// sensitivity and speed mouse configuration
public static final float MOUSE_SENSITIVITY = 0.05f; // mouse delta is multiplied by this
public static float MOVEMENT_SPEED = 10.0f; // world units per second
// the font to draw information to the screen
public static final Font ARIALFONT = new Font("Arial", Font.BOLD, 14);
public static final Font HEADERFONT = new Font("Arial", Font.BOLD, 26);
public static final Font DETAILFONT = new Font("Arial", Font.PLAIN, 13);
public static final Font DETAILVALUEFONT = new Font("Arial", Font.BOLD, 13);
public static final Font SMALLFONT = new Font("Arial", Font.PLAIN, 10);
// some convenience statics regarding time calculation
public static final long NANOSPERSECOND = 1000000000;
public static final long MILLISPERSECOND = 1000;
public static final long NANOSPERMILLIS = NANOSPERSECOND / MILLISPERSECOND;
// Types of blocks
public static enum BLOCK_TYPE {
NORMAL,
TORCH,
DECORATION_CROSS,
DECORATION_GRID,
LADDER,
FLOOR,
PRESSURE_PLATE,
HALFHEIGHT,
CAKE,
BED,
SNOW,
DOOR,
STAIRS,
SIGNPOST,
WALLSIGN,
FENCE,
FENCE_GATE,
LEVER,
BUTTON,
PORTAL,
MINECART_TRACKS,
SIMPLE_RAIL,
WATER,
SEMISOLID,
GLASS,
TRAPDOOR,
PISTON_BODY,
PISTON_HEAD,
VINE,
HUGE_MUSHROOM,
SOLID_PANE,
CHEST,
STEM,
END_PORTAL,
END_PORTAL_FRAME,
CAULDRON,
ENCHANTMENT_TABLE,
BREWING_STAND,
DRAGON_EGG
}
// Extra textures specified by various block types
public static HashMap<BLOCK_TYPE, String[]> blockTypeExtraTexturesReq =
new HashMap<BLOCK_TYPE, String[]>();
static
{
blockTypeExtraTexturesReq.put(BLOCK_TYPE.DOOR, new String[] {"bottom"});
blockTypeExtraTexturesReq.put(BLOCK_TYPE.MINECART_TRACKS, new String[] {"curve"});
blockTypeExtraTexturesReq.put(BLOCK_TYPE.SIMPLE_RAIL, new String[] {"powered"}); // actually just for powered rails, but whatever
blockTypeExtraTexturesReq.put(BLOCK_TYPE.CAKE, new String[] {"side_uncut", "side_cut", "bottom"});
blockTypeExtraTexturesReq.put(BLOCK_TYPE.BED, new String[] {"foot_top", "head_side", "foot_side", "foot", "head"});
blockTypeExtraTexturesReq.put(BLOCK_TYPE.PISTON_BODY, new String[] {"head", "back", "front"});
blockTypeExtraTexturesReq.put(BLOCK_TYPE.PISTON_HEAD, new String[] {"head_sticky", "body"});
blockTypeExtraTexturesReq.put(BLOCK_TYPE.CHEST, new String[] {"side_small", "top",
"front_big_left", "front_big_right",
"back_big_left", "back_big_right"});
blockTypeExtraTexturesReq.put(BLOCK_TYPE.HUGE_MUSHROOM, new String[] {"stem", "pores"});
blockTypeExtraTexturesReq.put(BLOCK_TYPE.STEM, new String[] {"curve"});
blockTypeExtraTexturesReq.put(BLOCK_TYPE.CAULDRON, new String[] {"inside", "top"});
blockTypeExtraTexturesReq.put(BLOCK_TYPE.ENCHANTMENT_TABLE, new String[] {"sides", "bottom"});
blockTypeExtraTexturesReq.put(BLOCK_TYPE.BREWING_STAND, new String[] {"base"});
blockTypeExtraTexturesReq.put(BLOCK_TYPE.LEVER, new String[] {"base"});
blockTypeExtraTexturesReq.put(BLOCK_TYPE.END_PORTAL_FRAME, new String[] {"sides", "bottom", "eye"});
}
// Our BLOCK structure is no longer an Enum, since we're reading it from a file
public static BlockTypeCollection blockCollection = new BlockTypeCollection();
// Just to omit one extra level of lookups, we'll also keep a reference to our
// block collection's ID-based array
public static BlockType[] blockArray;
// There are a few blocks that we know we need references to.
public static BlockType BLOCK_BEDROCK;
public static BlockType BLOCK_GRASS;
public static BlockType BLOCK_PORTAL;
public static BlockType BLOCK_END_PORTAL;
public static BlockType BLOCK_SAPLING;
public static BlockType BLOCK_FIRE;
public static BlockType BLOCK_WATER;
public static BlockType BLOCK_STATIONARY_WATER;
public static BlockType BLOCK_IRON_BARS;
public static BlockType BLOCK_PISTON_HEAD;
public static BlockType BLOCK_PISTON_STICKY_BODY;
public static BlockType BLOCK_SILVERFISH;
// A HashMap to define blocks that the "explored" highlight will use
public static HashMap<Short, Boolean> exploredBlocks;
// A meta-block to use for unknown block types
public static BlockType BLOCK_UNKNOWN;
// Some data to save for grass
public static HashMap<BlockType.DIRECTION_REL, Integer> grassDirectionMap;
// Block types to compute decoration information for
public static final BLOCK_TYPE[] DECORATION_BLOCKS = new BLOCK_TYPE[] {
BLOCK_TYPE.LEVER, BLOCK_TYPE.TORCH, BLOCK_TYPE.DECORATION_CROSS,
BLOCK_TYPE.DECORATION_GRID, BLOCK_TYPE.STEM,
BLOCK_TYPE.END_PORTAL_FRAME, BLOCK_TYPE.BREWING_STAND
};
// HIGHLIGHT_ORES defines the kinds of blocks that we'll highlight.
public static final String[] preferred_highlight_ores = new String[] {
"CLAY", "PUMPKIN", "OBSIDIAN", "COAL_ORE", "IRON_ORE",
"GOLD_ORE", "LAPIS_LAZULI_ORE", "DIAMOND_ORE", "REDSTONE_ORE", "MOB_SPAWNER"};
// Keyboard action categories
public static enum ACTION_CAT {
MOVEMENT ("Movement"),
CAMERA ("Camera"),
RENDERING ("Rendering"),
OTHER ("Other")
;
public String title;
ACTION_CAT(String title)
{
this.title = title;
}
}
// Keyboard actions
public static enum KEY_ACTION {
MOVE_FORWARD (ACTION_CAT.MOVEMENT, Keyboard.KEY_W, "Move Forward"),
MOVE_BACKWARD (ACTION_CAT.MOVEMENT, Keyboard.KEY_S, "Move Backward"),
MOVE_LEFT (ACTION_CAT.MOVEMENT, Keyboard.KEY_A, "Strafe Left"),
MOVE_RIGHT (ACTION_CAT.MOVEMENT, Keyboard.KEY_D, "Strafe Right"),
MOVE_UP (ACTION_CAT.MOVEMENT, Keyboard.KEY_SPACE, "Fly Up"),
MOVE_DOWN (ACTION_CAT.MOVEMENT, Keyboard.KEY_LCONTROL, "Fly Down"),
SPEED_INCREASE (ACTION_CAT.MOVEMENT, Keyboard.KEY_LSHIFT, "Move Faster"),
SPEED_DECREASE (ACTION_CAT.MOVEMENT, Keyboard.KEY_RSHIFT, "Move Slower"),
MOVE_TO_SPAWN (ACTION_CAT.CAMERA, Keyboard.KEY_HOME, "Jump to Spawnpoint"),
MOVE_TO_PLAYER (ACTION_CAT.CAMERA, Keyboard.KEY_END, "Jump to Player Position"),
MOVE_NEXT_CAMERAPOS (ACTION_CAT.CAMERA, Keyboard.KEY_INSERT, "Jump to Next Camera Preset"),
MOVE_PREV_CAMERAPOS (ACTION_CAT.CAMERA, Keyboard.KEY_DELETE, "Jump to Previous Camera Preset"),
JUMP (ACTION_CAT.CAMERA, Keyboard.KEY_J, "Jump to Abritrary Position"),
JUMP_NEAREST (ACTION_CAT.CAMERA, Keyboard.KEY_MINUS, "Jump to nearest existing chunk"),
DIMENSION_NEXT (ACTION_CAT.CAMERA, Keyboard.KEY_N, "Jump to Next Dimension"),
DIMENSION_PREV (ACTION_CAT.CAMERA, Keyboard.KEY_P, "Jump to Previous Dimension"),
TOGGLE_CAMERA_LOCK (ACTION_CAT.CAMERA, Keyboard.KEY_L, "Lock Camera to Vertical Axis"),
TOGGLE_ORE_1 (ACTION_CAT.RENDERING, Keyboard.KEY_F1, "Toggle Ore #1"),
TOGGLE_ORE_2 (ACTION_CAT.RENDERING, Keyboard.KEY_F2, "Toggle Ore #2"),
TOGGLE_ORE_3 (ACTION_CAT.RENDERING, Keyboard.KEY_F3, "Toggle Ore #3"),
TOGGLE_ORE_4 (ACTION_CAT.RENDERING, Keyboard.KEY_F4, "Toggle Ore #4"),
TOGGLE_ORE_5 (ACTION_CAT.RENDERING, Keyboard.KEY_F5, "Toggle Ore #5"),
TOGGLE_ORE_6 (ACTION_CAT.RENDERING, Keyboard.KEY_F6, "Toggle Ore #6"),
TOGGLE_ORE_7 (ACTION_CAT.RENDERING, Keyboard.KEY_F7, "Toggle Ore #7"),
TOGGLE_ORE_8 (ACTION_CAT.RENDERING, Keyboard.KEY_F8, "Toggle Ore #8"),
TOGGLE_ORE_9 (ACTION_CAT.RENDERING, Keyboard.KEY_F9, "Toggle Ore #9"),
TOGGLE_ORE_10 (ACTION_CAT.RENDERING, Keyboard.KEY_F10, "Toggle Ore #10"),
TOGGLE_ORE_HIGHLIGHTING (ACTION_CAT.RENDERING, Keyboard.KEY_H, "Toggle Ore Highlight Glow"),
HIGHLIGHT_RANGE_1 (ACTION_CAT.RENDERING, Keyboard.KEY_1, "Ore Highlight Distance 1"),
HIGHLIGHT_RANGE_2 (ACTION_CAT.RENDERING, Keyboard.KEY_2, "Ore Highlight Distance 2"),
HIGHLIGHT_RANGE_3 (ACTION_CAT.RENDERING, Keyboard.KEY_3, "Ore Highlight Distance 3"),
HIGHLIGHT_RANGE_4 (ACTION_CAT.RENDERING, Keyboard.KEY_4, "Ore Highlight Distance 4"),
HIGHLIGHT_RANGE_5 (ACTION_CAT.RENDERING, Keyboard.KEY_5, "Ore Highlight Distance 5"),
HIGHLIGHT_RANGE_6 (ACTION_CAT.RENDERING, Keyboard.KEY_6, "Ore Highlight Distance 6"),
HIGHLIGHT_RANGE_7 (ACTION_CAT.RENDERING, Keyboard.KEY_7, "Ore Highlight Distance 7"),
TOGGLE_FULLBRIGHT (ACTION_CAT.RENDERING, Keyboard.KEY_F, "Toggle Fullbright"),
TOGGLE_BEDROCK (ACTION_CAT.RENDERING, Keyboard.KEY_B, "Toggle Bedrock"),
TOGGLE_WATER (ACTION_CAT.RENDERING, Keyboard.KEY_T, "Toggle Water"),
LIGHT_INCREASE (ACTION_CAT.RENDERING, Keyboard.KEY_ADD, "Increase Lighting Range"),
LIGHT_DECREASE (ACTION_CAT.RENDERING, Keyboard.KEY_SUBTRACT, "Decrease Lighting Range"),
CHUNK_RANGE_1 (ACTION_CAT.RENDERING, Keyboard.KEY_NUMPAD1, "Visibility Range 1"),
CHUNK_RANGE_2 (ACTION_CAT.RENDERING, Keyboard.KEY_NUMPAD2, "Visibility Range 2"),
CHUNK_RANGE_3 (ACTION_CAT.RENDERING, Keyboard.KEY_NUMPAD3, "Visibility Range 3"),
CHUNK_RANGE_4 (ACTION_CAT.RENDERING, Keyboard.KEY_NUMPAD4, "Visibility Range 4"),
CHUNK_RANGE_5 (ACTION_CAT.RENDERING, Keyboard.KEY_NUMPAD5, "Visibility Range 5"),
CHUNK_RANGE_6 (ACTION_CAT.RENDERING, Keyboard.KEY_NUMPAD6, "Visibility Range 6"),
TOGGLE_HIGHLIGHT_EXPLORED (ACTION_CAT.RENDERING, Keyboard.KEY_E, "Toggle 'Explored' Areas"),
TOGGLE_ACCURATE_GRASS (ACTION_CAT.RENDERING, Keyboard.KEY_G, "Toggle Accurate Grass"),
TOGGLE_BETA19_FENCES (ACTION_CAT.RENDERING, Keyboard.KEY_C, "Toggle Beta 1.9 Fences"),
TOGGLE_SILVERFISH (ACTION_CAT.RENDERING, Keyboard.KEY_V, "Toggle Silverfish Highlighting"),
TOGGLE_CHUNK_BORDERS (ACTION_CAT.RENDERING, Keyboard.KEY_U, "Toggle Chunk Borders"),
TOGGLE_SLIME_CHUNKS (ACTION_CAT.RENDERING, Keyboard.KEY_M, "Toggle Slime Chunk Highlighting"),
TOGGLE_FULLSCREEN (ACTION_CAT.OTHER, Keyboard.KEY_BACK, "Toggle Fullscreen"),
TOGGLE_POSITION_INFO (ACTION_CAT.OTHER, Keyboard.KEY_GRAVE, "Toggle Level Info"),
TOGGLE_RENDER_DETAILS (ACTION_CAT.OTHER, Keyboard.KEY_R, "Toggle Rendering Info"),
OPEN_NEW_MAP (ACTION_CAT.OTHER, Keyboard.KEY_O, "Open New Map"),
RELOAD (ACTION_CAT.OTHER, Keyboard.KEY_EQUALS, "Reload Map from Disk"),
TOGGLE_MINIMAP (ACTION_CAT.OTHER, Keyboard.KEY_TAB, "Toggle Minimap"),
RELEASE_MOUSE (ACTION_CAT.OTHER, Keyboard.KEY_ESCAPE, "Release Mouse"),
KEY_HELP (ACTION_CAT.OTHER, Keyboard.KEY_Y, "Show Keyboard Reference"),
SET_ORE_BINDS (ACTION_CAT.OTHER, Keyboard.KEY_RBRACKET, "Set Ore Highlight Binds"),
QUIT (ACTION_CAT.OTHER, Keyboard.KEY_Q, "Quit")
;
public final ACTION_CAT category;
public final int def_key;
public final String desc;
KEY_ACTION(ACTION_CAT category, int def_key, String desc)
{
this.category = category;
this.def_key = def_key;
this.desc = desc;
}
}
public static final Block[] SURROUNDINGBLOCKS = new Block[] {
new Block(+1,0,0),
new Block(-1,0,0),
new Block(0,+1,0),
new Block(0,-1,0),
new Block(0,0,+1),
new Block(0,0,-1),
};
// Vars for painting information
public static HashMap<String, PaintingInfo> paintings;
public static PaintingInfo paintingback;
static void initialize()
throws BlockTypeLoadException
{
loadMainBlocks();
initSpriteSheetToTextureTable();
initPaintings();
// For now...
//BlockTypeCollection blockinfo = loadBlocks("blockdefs/aether.yaml");
//blockCollection.importFrom(blockinfo, true);
//TODO: Exceptions generated should really be saving our static state information (for later reporting)
for (BlockTypeCollection coll : MinecraftEnvironment.getBlockTypeCollectionFiles())
{
String g = "user";
if (coll.getGlobal())
{
g = "built-in";
}
if (coll.getException() == null)
{
// I think I will actually keep this the way it is, rather than create a GUI for
// loading these. As I noticed during the 1.8 prerelease stuff, as I had been
// testing Aethermod things, people using mods might be fairly likely to shuffle
// their minecraft.jar file around quite a bit. If I had gone forward with my
// previous plans, this would mean that whenever folks switched from, say, Aethermod
// to 1.8 (assuming here that Aethermod might take a little while to get updated
// to the 1.8 codebase), our stuff would disable Aether, and users would have to
// continually be going into that dialog to re-enable stuff.
//
// If we just auto-load everything all the time, then it should hopefully error
// out harmlessly on the ones that didn't load, and pick them up again once they
// can. Of course, this DOES open ourselves up to issues if two mods use the same
// block ID, and a user is switching back and forth between them. I feel okay
// requiring the user to manually swap out some blockdef files in that case, though.
try
{
// Do it without importing first. If there are some obvious errors then we'd catch
// them before potentially polluting our blockCollection with partial blockdef files
blockCollection.importFrom(coll, false);
blockCollection.importFrom(coll, true);
XRay.logger.debug("Got " + g + " blockdef " + coll.getName() + " (" + coll.getFile().getName() + "), " + coll.usedTextureCount() + " sheet textures, " + coll.getFilenameTextureCount() + " file textures");
}
catch (BlockTypeLoadException e)
{
XRay.logger.info("Error loading " + g + " blockdef at " + coll.getFile().getName() + ": " + e.toString());
}
}
else
{
XRay.logger.info("Error in " + g + " blockdef at " + coll.getFile().getName() + ": " + coll.getException().toString());
}
}
}
/**
* Reads in our default, base Minecraft texture data, and run a number of
* sanity checks on the data that we get.
*
* TODO: should this (or maybe just loadBlocks()) be in MinecraftEnvironment, maybe?
*/
public static void loadMainBlocks()
throws BlockTypeLoadException
{
// First load the blocks
BlockTypeCollection blockinfo = loadBlocks("blockdefs/minecraft.yaml", true);
// Import into blockCollection
blockCollection.importFrom(blockinfo, true);
// A number of blocks that we require be present
BLOCK_BEDROCK = blockCollection.getByName("BEDROCK");
if (BLOCK_BEDROCK == null)
{
throw new BlockTypeLoadException("BEDROCK block definition not found");
}
BLOCK_GRASS = blockCollection.getByName("GRASS");
if (BLOCK_GRASS == null)
{
throw new BlockTypeLoadException("GRASS block definition not found");
}
BLOCK_PORTAL = blockCollection.getByName("PORTAL");
if (BLOCK_PORTAL == null)
{
throw new BlockTypeLoadException("PORTAL block definition not found");
}
BLOCK_END_PORTAL = blockCollection.getByName("END_PORTAL");
if (BLOCK_END_PORTAL == null)
{
throw new BlockTypeLoadException("END_PORTAL block definition not found");
}
BLOCK_SAPLING = blockCollection.getByName("SAPLING");
if (BLOCK_SAPLING == null)
{
throw new BlockTypeLoadException("SAPLING block definition not found");
}
BLOCK_FIRE = blockCollection.getByName("FIRE");
if (BLOCK_FIRE == null)
{
throw new BlockTypeLoadException("FIRE block definition not found");
}
BLOCK_WATER = blockCollection.getByName("WATER");
if (BLOCK_WATER == null)
{
throw new BlockTypeLoadException("WATER block definition not found");
}
BLOCK_STATIONARY_WATER = blockCollection.getByName("STATIONARY_WATER");
if (BLOCK_STATIONARY_WATER == null)
{
throw new BlockTypeLoadException("STATIONARY_WATER block definition not found");
}
BLOCK_IRON_BARS = blockCollection.getByName("IRON_BARS");
if (BLOCK_IRON_BARS == null)
{
throw new BlockTypeLoadException("IRON_BARS block definition not found");
}
BLOCK_PISTON_HEAD = blockCollection.getByName("PISTON_HEAD");
if (BLOCK_PISTON_HEAD == null)
{
throw new BlockTypeLoadException("PISTON_HEAD block definition not found");
}
BLOCK_PISTON_STICKY_BODY = blockCollection.getByName("PISTON_STICKY_BODY");
if (BLOCK_PISTON_STICKY_BODY == null)
{
throw new BlockTypeLoadException("PISTON_STICKY_BODY block definition not found");
}
BLOCK_SILVERFISH = blockCollection.getByName("SILVERFISH");
if (BLOCK_SILVERFISH == null)
{
throw new BlockTypeLoadException("SILVERFISH block definition not found");
}
if (BLOCK_SILVERFISH.texture_data_map == null || !BLOCK_SILVERFISH.texture_data_map.containsKey((byte)0))
{
throw new BlockTypeLoadException("SILVERFISH block definition must include at least one data value of 0");
}
// We also define a "special" block for unknown block types, so that instead
// of empty space, they'll show up as purple blocks.
BLOCK_UNKNOWN = new BlockType();
BLOCK_UNKNOWN.setIdStr("SPECIAL_UNKNOWN");
BLOCK_UNKNOWN.setName("Internal Special Unknown Block");
BLOCK_UNKNOWN.color = new Color(214, 127, 255);
BLOCK_UNKNOWN.setType(BLOCK_TYPE.NORMAL);
// For grass, in particular, for its rendering toggle, we'll save some info
// that we can later tear out if need be.
grassDirectionMap = BLOCK_GRASS.texture_dir_map;
// Set our blockArray
blockArray = blockCollection.blockArray;
// Clean up.
ExceptionDialog.clearExtraStatus();
}
/**
* Reads in block information from a YAML file.
* TODO: should probably go elsewhere
*/
public static BlockTypeCollection loadBlocks(String filename, boolean global)
throws BlockTypeLoadException
{
ExceptionDialog.clearExtraStatus();
ExceptionDialog.setExtraStatus1("Loading blocks from " + filename);
// First load the actual YAML
BlockTypeCollection blockinfo;
try
{
blockinfo = BlockTypeCollection.loadFromYaml(filename, global);
}
catch (Exception e)
{
throw new BlockTypeLoadException("Could not load " + filename + ": " + e.toString(), e);
}
// Check to make sure our texfile exists, if it's defined
if (blockinfo.getTexfile() != null)
{
try
{
InputStream stream = MinecraftEnvironment.getMinecraftTexturepackData(blockinfo.getTexfile());
if (stream == null)
{
throw new BlockTypeLoadException("File " + blockinfo.getTexfile() + " is not found");
}
stream.close();
}
catch (IOException e)
{
throw new BlockTypeLoadException("Error while opening " + blockinfo.getTexfile() + ": " + e.toString(), e);
}
}
// Run through and normalize everything
blockinfo.normalizeBlocks();
// Return the blocks that we read
return blockinfo;
}
/***
* Sprite sheet texture index to texture coordinates
*/
public static void initSpriteSheetToTextureTable() {
precalcSpriteSheetToTextureX = new float[512];
precalcSpriteSheetToTextureY = new float[512];
for(int i=0;i<512;i++) {
float texYy = ((int) (i / 16))/32.0f;
float texXx = ((int) (i % 16))/16.0f;
precalcSpriteSheetToTextureX[i] = texXx;
precalcSpriteSheetToTextureY[i] = texYy;
}
}
/**
* Initialize our paintings. Note that our hashmap exepects to be
* in lowercase.
*/
public static void initPaintings() {
// I put these in here in the same order that they appeared at
// http://www.minecraftwiki.net/wiki/Painting
paintings = new HashMap<String, PaintingInfo>();
paintings.put("kebab", new PaintingInfo(1, 1, 0, 0));
paintings.put("aztec", new PaintingInfo(1, 1, 1, 0));
paintings.put("alban", new PaintingInfo(1, 1, 2, 0));
paintings.put("aztec2", new PaintingInfo(1, 1, 3, 0));
paintings.put("bomb", new PaintingInfo(1, 1, 4, 0));
paintings.put("plant", new PaintingInfo(1, 1, 5, 0));
paintings.put("wasteland", new PaintingInfo(1, 1, 6, 0));
paintings.put("wanderer", new PaintingInfo(1, 2, 0, 4));
paintings.put("graham", new PaintingInfo(1, 2, 1, 4));
paintings.put("pool", new PaintingInfo(2, 1, 0, 2));
paintings.put("courbet", new PaintingInfo(2, 1, 2, 2));
paintings.put("sunset", new PaintingInfo(2, 1, 6, 2));
paintings.put("sea", new PaintingInfo(2, 1, 4, 2));
paintings.put("creebet", new PaintingInfo(2, 1, 8, 2));
paintings.put("match", new PaintingInfo(2, 2, 0, 8));
paintings.put("bust", new PaintingInfo(2, 2, 2, 8));
paintings.put("stage", new PaintingInfo(2, 2, 4, 8));
paintings.put("void", new PaintingInfo(2, 2, 6, 8));
paintings.put("skullandroses", new PaintingInfo(2, 2, 8, 8));
paintings.put("fighters", new PaintingInfo(4, 2, 0, 6));
paintings.put("skeleton", new PaintingInfo(4, 3, 12, 4));
paintings.put("donkeykong", new PaintingInfo(4, 3, 12, 7));
paintings.put("pointer", new PaintingInfo(4, 4, 0, 12));
paintings.put("pigscene", new PaintingInfo(4, 4, 4, 12));
paintings.put("burningskull", new PaintingInfo(4, 4, 8, 12));
paintingback = new PaintingInfo(4, 4, 12, 0);
}
/**
* Get the text of the key that we want to display to the user
* @return The text to display for the key
*/
public static String getKeyEnglish(KEY_ACTION action, int bound_key)
{
if (Keyboard.getKeyName(bound_key).equals("GRAVE"))
{
return "`";
}
else if (Keyboard.getKeyName(bound_key).equals("SYSRQ"))
{
return "PRINTSCREEN";
}
else if (Keyboard.getKeyName(bound_key).equals("MINUS"))
{
return "-";
}
else
{
return Keyboard.getKeyName(bound_key);
}
}
/**
* Get any text which should be displayed after the key
* @return Text
*/
public static String getKeyExtraAfter(KEY_ACTION action, int bound_key)
{
switch (action)
{
case SPEED_INCREASE:
return " / Left Mouse Button (hold)";
case SPEED_DECREASE:
return " / Right Mouse Button (hold)";
default:
String key_name = Keyboard.getKeyName(bound_key);
if (key_name.startsWith("NUMPAD") || key_name.equals("DECIMAL"))
{
return " (numlock must be on)";
}
else if (key_name.equals("DIVIDE") || key_name.equals("MULTIPLY") ||
key_name.equals("SUBTRACT") || key_name.equals("ADD"))
{
return " (on numeric keypad)";
}
else if (key_name.equals("GRAVE"))
{
return " (grave accent)";
}
else if (key_name.equals("SYSRQ"))
{
return " (also called SYSRQ)";
}
else if (key_name.equals("MINUS"))
{
return " (minus, dash)";
}
break;
}
return "";
}
/**
* Get any text which should be displayed before the key
* @return Text
*/
public static String getKeyExtraBefore(KEY_ACTION action, int bound_key)
{
switch (action)
{
case QUIT:
return "CTRL-";
}
return "";
}
/**
* Returns a full text description of the given key
*/
public static String getKeyFullText(KEY_ACTION action, int bound_key)
{
return getKeyExtraBefore(action, bound_key) +
getKeyEnglish(action, bound_key) +
getKeyExtraAfter(action, bound_key);
}
}