From b04d766ab0d46db216a3ef7f9c036755e80bb0b4 Mon Sep 17 00:00:00 2001 From: EvilSeph Date: Fri, 12 Aug 2011 21:59:10 -0400 Subject: Added API for manipulating map items. Thanks SpaceManiac, codename_B, sk89q and dested! --- src/main/java/org/bukkit/Server.java | 19 +- src/main/java/org/bukkit/entity/Player.java | 9 + src/main/java/org/bukkit/event/Event.java | 6 + .../bukkit/event/server/MapInitializeEvent.java | 25 ++ .../org/bukkit/event/server/ServerListener.java | 7 + src/main/java/org/bukkit/map/MapCanvas.java | 75 +++++ src/main/java/org/bukkit/map/MapCursor.java | 160 ++++++++++ .../java/org/bukkit/map/MapCursorCollection.java | 86 ++++++ src/main/java/org/bukkit/map/MapFont.java | 127 ++++++++ src/main/java/org/bukkit/map/MapPalette.java | 150 ++++++++++ src/main/java/org/bukkit/map/MapRenderer.java | 50 ++++ src/main/java/org/bukkit/map/MapView.java | 133 +++++++++ src/main/java/org/bukkit/map/MinecraftFont.java | 328 +++++++++++++++++++++ .../org/bukkit/plugin/java/JavaPluginLoader.java | 7 + 14 files changed, 1181 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/bukkit/event/server/MapInitializeEvent.java create mode 100644 src/main/java/org/bukkit/map/MapCanvas.java create mode 100644 src/main/java/org/bukkit/map/MapCursor.java create mode 100644 src/main/java/org/bukkit/map/MapCursorCollection.java create mode 100644 src/main/java/org/bukkit/map/MapFont.java create mode 100644 src/main/java/org/bukkit/map/MapPalette.java create mode 100644 src/main/java/org/bukkit/map/MapRenderer.java create mode 100644 src/main/java/org/bukkit/map/MapView.java create mode 100644 src/main/java/org/bukkit/map/MinecraftFont.java (limited to 'src/main') diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java index fcac8541..d7dfe92d 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -12,6 +12,7 @@ import java.util.logging.Logger; import org.bukkit.command.PluginCommand; import org.bukkit.command.CommandSender; +import org.bukkit.map.MapView; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.ServicesManager; import org.bukkit.scheduler.BukkitScheduler; @@ -246,6 +247,22 @@ public interface Server { * @return World with the given Unique ID, or null if none exists. */ public World getWorld(UUID uid); + + /** + * Gets the map from the given item ID. + * + * @param id ID of the map to get. + * @return The MapView if it exists, or null otherwise. + */ + public MapView getMap(short id); + + /** + * Create a new map with an automatically assigned ID. + * + * @param world The world the map will belong to. + * @return The MapView just created. + */ + public MapView createMap(World world); /** * Reloads the server, refreshing settings and plugin information @@ -329,4 +346,4 @@ public interface Server { * @return Whether this server allows flying or not. */ public boolean getAllowFlight(); -} \ No newline at end of file +} diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java index edce853c..706f1fd9 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java @@ -9,6 +9,7 @@ import org.bukkit.Material; import org.bukkit.Note; import org.bukkit.Statistic; import org.bukkit.command.CommandSender; +import org.bukkit.map.MapView; /** * Represents a player, connected or not @@ -202,6 +203,14 @@ public interface Player extends HumanEntity, CommandSender { * @param data */ public void sendBlockChange(Location loc, int material, byte data); + + /** + * Render a map and send it to the player in its entirety. This may be used + * when streaming the map in the normal manner is not desirbale. + * + * @pram map The map to be sent + */ + public void sendMap(MapView map); /** * Forces an update of the player's entire inventory. diff --git a/src/main/java/org/bukkit/event/Event.java b/src/main/java/org/bukkit/event/Event.java index 233d8214..acfb252c 100644 --- a/src/main/java/org/bukkit/event/Event.java +++ b/src/main/java/org/bukkit/event/Event.java @@ -487,6 +487,12 @@ public abstract class Event implements Serializable { * @see org.bukkit.event.server.ServerCommandEvent */ SERVER_COMMAND (Category.SERVER), + /** + * Called when a map is initialized (created or loaded into memory) + * + * @see org.bukkit.event.server.MapInitializeEvent + */ + MAP_INITIALIZE (Category.SERVER), /** * WORLD EVENTS diff --git a/src/main/java/org/bukkit/event/server/MapInitializeEvent.java b/src/main/java/org/bukkit/event/server/MapInitializeEvent.java new file mode 100644 index 00000000..12ef1781 --- /dev/null +++ b/src/main/java/org/bukkit/event/server/MapInitializeEvent.java @@ -0,0 +1,25 @@ +package org.bukkit.event.server; + +import org.bukkit.event.Event; +import org.bukkit.map.MapView; + +/** + * Called when a map is initialized. + */ +public class MapInitializeEvent extends ServerEvent { + private final MapView mapView; + + public MapInitializeEvent(MapView mapView) { + super(Event.Type.MAP_INITIALIZE); + this.mapView = mapView; + } + + /** + * Gets the map initialized in this event. + * + * @return Map for this event + */ + public MapView getMap() { + return mapView; + } +} diff --git a/src/main/java/org/bukkit/event/server/ServerListener.java b/src/main/java/org/bukkit/event/server/ServerListener.java index f2434b5e..f4bf722a 100644 --- a/src/main/java/org/bukkit/event/server/ServerListener.java +++ b/src/main/java/org/bukkit/event/server/ServerListener.java @@ -27,4 +27,11 @@ public class ServerListener implements Listener { * @param event Relevant event details */ public void onServerCommand(ServerCommandEvent event) {} + + /** + * Called when a map item is initialized (created or loaded into memory) + * + * @param event Relevant event details + */ + public void onMapInitialize(MapInitializeEvent event) {} } diff --git a/src/main/java/org/bukkit/map/MapCanvas.java b/src/main/java/org/bukkit/map/MapCanvas.java new file mode 100644 index 00000000..274d0a88 --- /dev/null +++ b/src/main/java/org/bukkit/map/MapCanvas.java @@ -0,0 +1,75 @@ +package org.bukkit.map; + +import java.awt.Image; + +/** + * Represents a canvas for drawing to a map. Each canvas is associated with a + * specific {@link MapRenderer} and represents that renderer's layer on the map. + */ +public interface MapCanvas { + + /** + * Get the map this canvas is attached to. + * @return The MapView this canvas is attached to. + */ + public MapView getMapView(); + + /** + * Get the cursor collection associated with this canvas. + * @return The MapCursorCollection associated with this canvas. + */ + public MapCursorCollection getCursors(); + + /** + * Set the cursor collection associated with this canvas. This does not + * usually need to be called since a MapCursorCollection is already + * provided. + * @param cursors The MapCursorCollection to associate with this canvas. + */ + public void setCursors(MapCursorCollection cursors); + + /** + * Draw a pixel to the canvas. + * @param x The x coordinate, from 0 to 127. + * @param y The y coordinate, from 0 to 127. + * @param color The color. See {@link MapPalette}. + */ + public void setPixel(int x, int y, byte color); + + /** + * Get a pixel from the canvas. + * @param x The x coordinate, from 0 to 127. + * @param y The y coordinate, from 0 to 127. + * @return The color. See {@link MapPalette}. + */ + public byte getPixel(int x, int y); + + /** + * Get a pixel from the layers below this canvas. + * @param x The x coordinate, from 0 to 127. + * @param y The y coordinate, from 0 to 127. + * @return The color. See {@link MapPalette}. + */ + public byte getBasePixel(int x, int y); + + /** + * Draw an image to the map. The image will be clipped if necessary. + * @param x The x coordinate of the image. + * @param y The y coordinate of the image. + * @param image The Image to draw. + */ + public void drawImage(int x, int y, Image image); + + /** + * Render text to the map using fancy formatting. Newline (\n) characters + * will move down one line and return to the original column, and the text + * color can be changed using sequences such as "§12;", replacing 12 with + * the palette index of the color (see {@link MapPalette}). + * @param map The MapInfo to render to. + * @param x The column to start rendering on. + * @param y The row to start rendering on. + * @param text The formatted text to render. + */ + public void drawText(int x, int y, MapFont font, String text); + +} diff --git a/src/main/java/org/bukkit/map/MapCursor.java b/src/main/java/org/bukkit/map/MapCursor.java new file mode 100644 index 00000000..957db93b --- /dev/null +++ b/src/main/java/org/bukkit/map/MapCursor.java @@ -0,0 +1,160 @@ +package org.bukkit.map; + +/** + * Represents a cursor on a map. + */ +public final class MapCursor { + + private byte x, y; + private byte direction, type; + private boolean visible; + + /** + * Initialize the map cursor. + * @param x The x coordinate, from -128 to 127. + * @param y The y coordinate, from -128 to 127. + * @param direction The facing of the cursor, from 0 to 15. + * @param type The type (color/style) of the map cursor. + * @param visible Whether the cursor is visible by default. + */ + public MapCursor(byte x, byte y, byte direction, byte type, boolean visible) { + this.x = x; + this.y = y; + setDirection(direction); + setRawType(type); + this.visible = visible; + } + + /** + * Get the X position of this cursor. + * @return The X coordinate. + */ + public byte getX() { + return x; + } + + /** + * Get the Y position of this cursor. + * @return The Y coordinate. + */ + public byte getY() { + return y; + } + + /** + * Get the direction of this cursor. + * @return The facing of the cursor, from 0 to 15. + */ + public byte getDirection() { + return direction; + } + + /** + * Get the type of this cursor. + * @return The type (color/style) of the map cursor. + */ + public Type getType() { + return Type.byValue(type); + } + + /** + * Get the type of this cursor. + * @return The type (color/style) of the map cursor. + */ + public byte getRawType() { + return type; + } + + /** + * Get the visibility status of this cursor. + * @return True if visible, false otherwise. + */ + public boolean isVisible() { + return visible; + } + + /** + * Set the X position of this cursor. + * @param x The X coordinate. + */ + public void setX(byte x) { + this.x = x; + } + + /** + * Set the Y position of this cursor. + * @param y The Y coordinate. + */ + public void setY(byte y) { + this.y = y; + } + + /** + * Set the direction of this cursor. + * @param direction The facing of the cursor, from 0 to 15. + */ + public void setDirection(byte direction) { + if (direction < 0 || direction > 15) { + throw new IllegalArgumentException("Direction must be in the range 0-15"); + } + this.direction = direction; + } + + /** + * Set the type of this cursor. + * @param type The type (color/style) of the map cursor. + */ + public void setType(Type type) { + setRawType(type.value); + } + + /** + * Set the type of this cursor. + * @param type The type (color/style) of the map cursor. + */ + public void setRawType(byte type) { + if (type < 0 || type > 15) { + throw new IllegalArgumentException("Type must be in the range 0-15"); + } + this.type = type; + } + + /** + * Set the visibility status of this cursor. + * @param visible True if visible. + */ + public void setVisible(boolean visible) { + this.visible = visible; + } + + /** + * Represents the standard types of map cursors. More may be made available + * by texture packs - the value is used by the client as an index in the + * file './misc/mapicons.png' from minecraft.jar or from a texture pack. + */ + public enum Type { + WHITE_POINTER(0), + GREEN_POINTER(1), + RED_POINTER(2), + BLUE_POINTER(3), + WHITE_CROSS(4); + + private byte value; + + private Type(int value) { + this.value = (byte) value; + } + + public byte getValue() { + return value; + } + + public static Type byValue(byte value) { + for (Type t : values()) { + if (t.value == value) return t; + } + return null; + } + } + +} diff --git a/src/main/java/org/bukkit/map/MapCursorCollection.java b/src/main/java/org/bukkit/map/MapCursorCollection.java new file mode 100644 index 00000000..ac5d3e30 --- /dev/null +++ b/src/main/java/org/bukkit/map/MapCursorCollection.java @@ -0,0 +1,86 @@ +package org.bukkit.map; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents all the map cursors on a {@link MapCanvas}. Like MapCanvas, a + * MapCursorCollection is linked to a specific {@link MapRenderer}. + */ +public final class MapCursorCollection { + + private List cursors = new ArrayList(); + + /** + * Get the amount of cursors in this collection. + * @return The size of this collection. + */ + public int size() { + return cursors.size(); + } + + /** + * Get a cursor from this collection. + * @param index The index of the cursor. + * @return The MapCursor. + */ + public MapCursor getCursor(int index) { + return cursors.get(index); + } + + /** + * Remove a cursor from the collection. + * @param cursor The MapCursor to remove. + * @return Whether the cursor was removed successfully. + */ + public boolean removeCursor(MapCursor cursor) { + return cursors.remove(cursor); + } + + /** + * Add a cursor to the collection. + * @param cursor The MapCursor to add. + * @return The MapCursor that was passed. + */ + public MapCursor addCursor(MapCursor cursor) { + cursors.add(cursor); + return cursor; + } + + /** + * Add a cursor to the collection. + * @param x The x coordinate, from -128 to 127. + * @param y The y coordinate, from -128 to 127. + * @param direction The facing of the cursor, from 0 to 15. + * @return The newly added MapCursor. + */ + public MapCursor addCursor(int x, int y, byte direction) { + return addCursor(x, y, direction, (byte) 0, true); + } + + /** + * Add a cursor to the collection. + * @param x The x coordinate, from -128 to 127. + * @param y The y coordinate, from -128 to 127. + * @param direction The facing of the cursor, from 0 to 15. + * @param type The type (color/style) of the map cursor. + * @return The newly added MapCursor. + */ + public MapCursor addCursor(int x, int y, byte direction, byte type) { + return addCursor(x, y, direction, type, true); + } + + /** + * Add a cursor to the collection. + * @param x The x coordinate, from -128 to 127. + * @param y The y coordinate, from -128 to 127. + * @param direction The facing of the cursor, from 0 to 15. + * @param type The type (color/style) of the map cursor. + * @param visible Whether the cursor is visible. + * @return The newly added MapCursor. + */ + public MapCursor addCursor(int x, int y, byte direction, byte type, boolean visible) { + return addCursor(new MapCursor((byte) x, (byte) y, direction, type, visible)); + } + +} diff --git a/src/main/java/org/bukkit/map/MapFont.java b/src/main/java/org/bukkit/map/MapFont.java new file mode 100644 index 00000000..6d38d525 --- /dev/null +++ b/src/main/java/org/bukkit/map/MapFont.java @@ -0,0 +1,127 @@ +package org.bukkit.map; + +import java.util.HashMap; + +/** + * Represents a bitmap font drawable to a map. + */ +public class MapFont { + + private final HashMap chars = new HashMap(); + private int height = 0; + protected boolean malleable = true; + + /** + * Set the sprite for a given character. + * @param ch The character to set the sprite for. + * @param sprite The CharacterSprite to set. + * @throws IllegalStateException if this font is static. + */ + public void setChar(char ch, CharacterSprite sprite) { + if (!malleable) { + throw new IllegalStateException("this font is not malleable"); + } + + chars.put(ch, sprite); + if (sprite.getHeight() > height) { + height = sprite.getHeight(); + } + } + + /** + * Get the sprite for a given character. + * @param ch The character to get the sprite for. + * @return The CharacterSprite associated with the character, or null if there is none. + */ + public CharacterSprite getChar(char ch) { + return chars.get(ch); + } + + /** + * Get the width of the given text as it would be rendered using this font. + * @param text The text. + * @return The width in pixels. + */ + public int getWidth(String text) { + if (!isValid(text)) { + throw new IllegalArgumentException("text contains invalid characters"); + } + + int result = 0; + for (int i = 0; i < text.length(); ++i) { + result += chars.get(text.charAt(i)).getWidth(); + } + return result; + } + + /** + * Get the height of this font. + * @return The height of the font. + */ + public int getHeight() { + return height; + } + + /** + * Check whether the given text is valid. + * @param text The text. + * @return True if the string contains only defined characters, false otherwise. + */ + public boolean isValid(String text) { + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch == '\u00A7' || ch == '\n') continue; + if (chars.get(ch) == null) return false; + } + return true; + } + + /** + * Represents the graphics for a single character in a MapFont. + */ + public static class CharacterSprite { + + private final int width; + private final int height; + private final boolean[] data; + + public CharacterSprite(int width, int height, boolean[] data) { + this.width = width; + this.height = height; + this.data = data; + + if (data.length != width * height) { + throw new IllegalArgumentException("size of data does not match dimensions"); + } + } + + /** + * Get the value of a pixel of the character. + * @param row The row, in the range [0,8). + * @param col The column, in the range [0,8). + * @return True if the pixel is solid, false if transparent. + */ + public boolean get(int row, int col) { + if (row < 0 || col < 0 || row >= height || col >= width) return false; + return data[row * width + col]; + } + + /** + * Get the width of the character sprite. + * @return The width of the character. + */ + public int getWidth() { + return width; + } + + /** + * Get the height of the character sprite. + * @return The height of the character. + */ + public int getHeight() { + return height; + } + + } + +} diff --git a/src/main/java/org/bukkit/map/MapPalette.java b/src/main/java/org/bukkit/map/MapPalette.java new file mode 100644 index 00000000..dcc254ea --- /dev/null +++ b/src/main/java/org/bukkit/map/MapPalette.java @@ -0,0 +1,150 @@ +package org.bukkit.map; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.BufferedImage; + +/** + * Represents the palette that map items use. + */ +public final class MapPalette { + + // Internal mechanisms + + private MapPalette() {} + + private static Color c(int r, int g, int b) { + return new Color(r, g, b); + } + + private static double getDistance(Color c1, Color c2) { + double rmean = (c1.getRed() + c2.getRed()) / 2.0; + double r = c1.getRed() - c2.getRed(); + double g = c1.getGreen() - c2.getGreen(); + int b = c1.getBlue() - c2.getBlue(); + double weightR = 2 + rmean / 256.0; + double weightG = 4.0; + double weightB = 2 + (255 - rmean) / 256.0; + return weightR * r * r + weightG * g * g + weightB * b * b; + } + + private static final Color[] colors = { + new Color(0, 0, 0, 0), new Color(0, 0, 0, 0), + new Color(0, 0, 0, 0), new Color(0, 0, 0, 0), + c(89,125,39), c(109,153,48), c(27,178,56), c(109,153,48), + c(174,164,115), c(213,201,140), c(247,233,163), c(213,201,140), + c(117,117,117), c(144,144,144), c(167,167,167), c(144,144,144), + c(180,0,0), c(220,0,0), c(255,0,0), c(220,0,0), + c(112,112,180), c(138,138,220), c(160,160,255), c(138,138,220), + c(117,117,117), c(144,144,144), c(167,167,167), c(144,144,144), + c(0,87,0), c(0,106,0), c(0,124,0), c(0,106,0), + c(180,180,180), c(220,220,220), c(255,255,255), c(220,220,220), + c(115,118,129), c(141,144,158), c(164,168,184), c(141,144,158), + c(129,74,33), c(157,91,40), c(183,106,47), c(157,91,40), + c(79,79,79), c(96,96,96), c(112,112,112), c(96,96,96), + c(45,45,180), c(55,55,220), c(64,64,255), c(55,55,220), + c(73,58,35), c(89,71,43), c(104,83,50), c(89,71,43) + }; + + // Interface + + /** + * The base color ranges. Each entry corresponds to four colors of varying + * shades with values entry to entry + 3. + */ + public static final byte TRANSPARENT = 0; + public static final byte LIGHT_GREEN = 4; + public static final byte LIGHT_BROWN = 8; + public static final byte GRAY_1 = 12; + public static final byte RED = 16; + public static final byte PALE_BLUE = 20; + public static final byte GRAY_2 = 24; + public static final byte DARK_GREEN = 28; + public static final byte WHITE = 32; + public static final byte LIGHT_GRAY = 36; + public static final byte BROWN = 40; + public static final byte DARK_GRAY = 44; + public static final byte BLUE = 48; + public static final byte DARK_BROWN = 52; + /** + * Resize an image to 128x128. + * @param image The image to resize. + * @return The resized image. + */ + public static BufferedImage resizeImage(Image image) { + BufferedImage result = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB); + Graphics2D graphics = result.createGraphics(); + graphics.drawImage(image, 0, 0, 128, 128, null); + graphics.dispose(); + return result; + } + + /** + * Convert an Image to a byte[] using the palette. + * @param image The image to convert. + * @return A byte[] containing the pixels of the image. + */ + public static byte[] imageToBytes(Image image) { + BufferedImage temp = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); + Graphics2D graphics = temp.createGraphics(); + graphics.drawImage(image, 0, 0, null); + graphics.dispose(); + + int[] pixels = new int[temp.getWidth() * temp.getHeight()]; + temp.getRGB(0, 0, temp.getWidth(), temp.getHeight(), pixels, 0, temp.getWidth()); + + byte[] result = new byte[temp.getWidth() * temp.getHeight()]; + for (int i = 0; i < pixels.length; i++) { + result[i] = matchColor(new Color(pixels[i])); + } + return result; + } + + /** + * Get the index of the closest matching color in the palette to the given color. + * @param r The red component of the color. + * @param b The blue component of the color. + * @param g The green component of the color. + * @return The index in the palette. + */ + public static byte matchColor(int r, int g, int b) { + return matchColor(new Color(r, g, b)); + } + + /** + * Get the index of the closest matching color in the palette to the given color. + * @param color The Color to match. + * @return The index in the palette. + */ + public static byte matchColor(Color color) { + if (color.getAlpha() < 128) return 0; + + int index = 0; + double best = -1; + + for (int i = 4; i < colors.length; i++) { + double distance = getDistance(color, colors[i]); + if (distance < best || best == -1) { + best = distance; + index = i; + } + } + + return (byte) index; + } + + /** + * Get the value of the given color in the palette. + * @param index The index in the palette. + * @return The Color of the palette entry. + */ + public static Color getColor(byte index) { + if (index < 0 || index >= colors.length) { + throw new IndexOutOfBoundsException(); + } else { + return colors[index]; + } + } + +} diff --git a/src/main/java/org/bukkit/map/MapRenderer.java b/src/main/java/org/bukkit/map/MapRenderer.java new file mode 100644 index 00000000..f0ffd6bb --- /dev/null +++ b/src/main/java/org/bukkit/map/MapRenderer.java @@ -0,0 +1,50 @@ +package org.bukkit.map; + +import org.bukkit.entity.Player; + +/** + * Represents a renderer for a map. + */ +public abstract class MapRenderer { + + private boolean contextual; + + /** + * Initialize the map renderer base to be non-contextual. See {@link isContextual}. + */ + public MapRenderer() { + this(false); + } + + /** + * Initialize the map renderer base with the given contextual status. + * @param contextual Whether the renderer is contextual. See {@link isContextual}. + */ + public MapRenderer(boolean contextual) { + this.contextual = contextual; + } + + /** + * Get whether the renderer is contextual, i.e. has different canvases for + * different players. + * @return True if contextual, false otherwise. + */ + final public boolean isContextual() { + return contextual; + } + + /** + * Initialize this MapRenderer for the given map. + * @param map The MapView being initialized. + */ + public void initialize(MapView map) { } + + /** + * Render to the given map. + * @param map The MapView being rendered to. + * @param canvas The canvas to use for rendering. + * @param player The player who triggered the rendering. + */ + abstract public void render(MapView map, MapCanvas canvas, Player player); + +} diff --git a/src/main/java/org/bukkit/map/MapView.java b/src/main/java/org/bukkit/map/MapView.java new file mode 100644 index 00000000..ca0e4d78 --- /dev/null +++ b/src/main/java/org/bukkit/map/MapView.java @@ -0,0 +1,133 @@ +package org.bukkit.map; + +import java.util.List; +import org.bukkit.World; + +/** + * Represents a map item. + */ +public interface MapView { + + /** + * An enum representing all possible scales a map can be set to. + */ + public static enum Scale { + CLOSEST(0), + CLOSE(1), + NORMAL(2), + FAR(3), + FARTHEST(4); + + private byte value; + + private Scale(int value) { + this.value = (byte) value; + } + + /** + * Get the scale given the raw value. + */ + public static Scale valueOf(byte value) { + switch(value) { + case 0: return CLOSEST; + case 1: return CLOSE; + case 2: return NORMAL; + case 3: return FAR; + case 4: return FARTHEST; + default: return null; + } + } + + /** + * Get the raw value of this scale level. + */ + public byte getValue() { + return value; + } + } + + /** + * Get the ID of this map item. Corresponds to the damage value of a map + * in an inventory. + * @return The ID of the map. + */ + public short getId(); + + /** + * Check whether this map is virtual. A map is virtual if its lowermost + * MapRenderer is plugin-provided. + * @return Whether the map is virtual. + */ + public boolean isVirtual(); + + /** + * Get the scale of this map. + * @return The scale of the map. + */ + public Scale getScale(); + + /** + * Set the scale of this map. + * @param scale The scale to set. + */ + public void setScale(Scale scale); + + /** + * Get the center X position of this map. + * @return The center X position. + */ + public int getCenterX(); + + /** + * Get the center Z position of this map. + * @return The center Z position. + */ + public int getCenterZ(); + + /** + * Set the center X position of this map. + * @param x The center X position. + */ + public void setCenterX(int x); + + /** + * Set the center Z position of this map. + * @param z The center Z position. + */ + public void setCenterZ(int z); + + /** + * Get the world that this map is associated with. Primarily used by the + * internal renderer, but may be used by external renderers. May return + * null if the world the map is associated with is not loaded. + * @return The World this map is associated with. + */ + public World getWorld(); + + /** + * Set the world that this map is associated with. The world is used by + * the internal renderer, and may also be used by external renderers. + * @param world The World to associate this map with. + */ + public void setWorld(World world); + + /** + * Get a list of MapRenderers currently in effect. + * @return A List containing each map renderer. + */ + public List getRenderers(); + + /** + * Add a renderer to this map. + * @param renderer The MapRenderer to add. + */ + public void addRenderer(MapRenderer renderer); + + /** + * Remove a renderer from this map. + * @param renderer The MapRenderer to remove. + * @return True if the renderer was successfully removed. + */ + public boolean removeRenderer(MapRenderer renderer); + +} diff --git a/src/main/java/org/bukkit/map/MinecraftFont.java b/src/main/java/org/bukkit/map/MinecraftFont.java new file mode 100644 index 00000000..d84d5c2f --- /dev/null +++ b/src/main/java/org/bukkit/map/MinecraftFont.java @@ -0,0 +1,328 @@ +package org.bukkit.map; + +/** + * Represents the built-in Minecraft font. + */ +public class MinecraftFont extends MapFont { + + private static final int spaceSize = 2; + + private static final String fontChars = + " !\"#$%&'()*+,-./0123456789:;<=>?" + + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" + + "'abcdefghijklmnopqrstuvwxyz{|}~\u007F" + + "\u00C7\u00FC\u00E9\u00E2\u00E4\u00E0\u00E5\u00E7" + // Çüéâäàåç + "\u00EA\u00EB\u00E8\u00EF\u00EE\u00EC\u00C4\u00C5" + // êëèïîìÄÅ + "\u00C9\u00E6\u00C6\u00F4\u00F6\u00F2\u00FB\u00F9" + // ÉæÆôöòûù + "\u00FF\u00D6\u00DC\u00F8\u00A3\u00D8\u00D7\u0191" + // ÿÖÜø£Ø׃ + "\u00E1\u00ED\u00F3\u00FA\u00F1\u00D1\u00AA\u00BA" + // áíóúñѪº + "\u00BF\u00AE\u00AC\u00BD\u00BC\u00A1\u00AB\u00BB"; // ¿®¬½¼¡«» + + private static final int[][] fontData = new int[][] { + /* null */ {0,0,0,0,0,0,0,0}, + /* 1 */ {126,129,165,129,189,153,129,126}, + /* 2 */ {126,255,219,255,195,231,255,126}, + /* 3 */ {54,127,127,127,62,28,8,0}, + /* 4 */ {8,28,62,127,62,28,8,0}, + /* 5 */ {28,62,28,127,127,62,28,62}, + /* 6 */ {8,8,28,62,127,62,28,62}, + /* 7 */ {0,0,24,60,60,24,0,0}, + /* 8 */ {255,255,231,195,195,231,255,255}, + /* 9 */ {0,60,102,66,66,102,60,0}, + /* 10 */ {255,195,153,189,189,153,195,255}, + /* 11 */ {240,224,240,190,51,51,51,30}, + /* 12 */ {60,102,102,102,60,24,126,24}, + /* 13 */ {252,204,252,12,12,14,15,7}, + /* 14 */ {254,198,254,198,198,230,103,3}, + /* 15 */ {153,90,60,231,231,60,90,153}, + /* 16 */ {1,7,31,127,31,7,1,0}, + /* 17 */ {64,112,124,127,124,112,64,0}, + /* 18 */ {24,60,126,24,24,126,60,24}, + /* 19 */ {102,102,102,102,102,0,102,0}, + /* 20 */ {254,219,219,222,216,216,216,0}, + /* 21 */ {124,198,28,54,54,28,51,30}, + /* 22 */ {0,0,0,0,126,126,126,0}, + /* 23 */ {24,60,126,24,126,60,24,255}, + /* 24 */ {24,60,126,24,24,24,24,0}, + /* 25 */ {24,24,24,24,126,60,24,0}, + /* 26 */ {0,24,48,127,48,24,0,0}, + /* 27 */ {0,12,6,127,6,12,0,0}, + /* 28 */ {0,0,3,3,3,127,0,0}, + /* 29 */ {0,36,102,255,102,36,0,0}, + /* 30 */ {0,24,60,126,255,255,0,0}, + /* 31 */ {0,255,255,126,60,24,0,0}, + /* */ {0,0,0,0,0,0,0,0}, + /* ! */ {1,1,1,1,1,0,1,0}, + /* " */ {10,10,5,0,0,0,0,0}, + /* # */ {10,10,31,10,31,10,10,0}, + /* $ */ {4,30,1,14,16,15,4,0}, + /* % */ {17,9,8,4,2,18,17,0}, + /* & */ {4,10,4,22,13,9,22,0}, + /* ' */ {2,2,1,0,0,0,0,0}, + /* ( */ {12,2,1,1,1,2,12,0}, + /* ) */ {3,4,8,8,8,4,3,0}, + /* * */ {0,0,9,6,9,0,0,0}, + /* + */ {0,4,4,31,4,4,0,0}, + /* , */ {0,0,0,0,0,1,1,1}, + /* - */ {0,0,0,31,0,0,0,0}, + /* . */ {0,0,0,0,0,1,1,0}, + /* / */ {16,8,8,4,2,2,1,0}, + /* 0 */ {14,17,25,21,19,17,14,0}, + /* 1 */ {4,6,4,4,4,4,31,0}, + /* 2 */ {14,17,16,12,2,17,31,0}, + /* 3 */ {14,17,16,12,16,17,14,0}, + /* 4 */ {24,20,18,17,31,16,16,0}, + /* 5 */ {31,1,15,16,16,17,14,0}, + /* 6 */ {12,2,1,15,17,17,14,0}, + /* 7 */ {31,17,16,8,4,4,4,0}, + /* 8 */ {14,17,17,14,17,17,14,0}, + /* 9 */ {14,17,17,30,16,8,6,0}, + /* : */ {0,1,1,0,0,1,1,0}, + /* ; */ {0,1,1,0,0,1,1,1}, + /* < */ {8,4,2,1,2,4,8,0}, + /* = */ {0,0,31,0,0,31,0,0}, + /* > */ {1,2,4,8,4,2,1,0}, + /* ? */ {14,17,16,8,4,0,4,0}, + /* @ */ {30,33,45,45,61,1,30,0}, + /* A */ {14,17,31,17,17,17,17,0}, + /* B */ {15,17,15,17,17,17,15,0}, + /* C */ {14,17,1,1,1,17,14,0}, + /* D */ {15,17,17,17,17,17,15,0}, + /* E */ {31,1,7,1,1,1,31,0}, + /* F */ {31,1,7,1,1,1,1,0}, + /* G */ {30,1,25,17,17,17,14,0}, + /* H */ {17,17,31,17,17,17,17,0}, + /* I */ {7,2,2,2,2,2,7,0}, + /* J */ {16,16,16,16,16,17,14,0}, + /* K */ {17,9,7,9,17,17,17,0}, + /* L */ {1,1,1,1,1,1,31,0}, + /* M */ {17,27,21,17,17,17,17,0}, + /* N */ {17,19,21,25,17,17,17,0}, + /* O */ {14,17,17,17,17,17,14,0}, + /* P */ {15,17,15,1,1,1,1,0}, + /* Q */ {14,17,17,17,17,9,22,0}, + /* R */ {15,17,15,17,17,17,17,0}, + /* S */ {30,1,14,16,16,17,14,0}, + /* T */ {31,4,4,4,4,4,4,0}, + /* U */ {17,17,17,17,17,17,14,0}, + /* V */ {17,17,17,17,10,10,4,0}, + /* W */ {17,17,17,17,21,27,17,0}, + /* X */ {17,10,4,10,17,17,17,0}, + /* Y */ {17,10,4,4,4,4,4,0}, + /* Z */ {31,16,8,4,2,1,31,0}, + /* [ */ {7,1,1,1,1,1,7,0}, + /* \ */ {1,2,2,4,8,8,16,0}, + /* ] */ {7,4,4,4,4,4,7,0}, + /* ^ */ {4,10,17,0,0,0,0,0}, + /* _ */ {0,0,0,0,0,0,0,31}, + /* ` */ {1,1,2,0,0,0,0,0}, + /* a */ {0,0,14,16,30,17,30,0}, + /* b */ {1,1,13,19,17,17,15,0}, + /* c */ {0,0,14,17,1,17,14,0}, + /* d */ {16,16,22,25,17,17,30,0}, + /* e */ {0,0,14,17,31,1,30,0}, + /* f */ {12,2,15,2,2,2,2,0}, + /* g */ {0,0,30,17,17,30,16,15}, + /* h */ {1,1,13,19,17,17,17,0}, + /* i */ {1,0,1,1,1,1,1,0}, + /* j */ {16,0,16,16,16,17,17,14}, + /* k */ {1,1,9,5,3,5,9,0}, + /* l */ {1,1,1,1,1,1,2,0}, + /* m */ {0,0,11,21,21,17,17,0}, + /* n */ {0,0,15,17,17,17,17,0}, + /* o */ {0,0,14,17,17,17,14,0}, + /* p */ {0,0,13,19,17,15,1,1}, + /* q */ {0,0,22,25,17,30,16,16}, + /* r */ {0,0,13,19,1,1,1,0}, + /* s */ {0,0,30,1,14,16,15,0}, + /* t */ {2,2,7,2,2,2,4,0}, + /* u */ {0,0,17,17,17,17,30,0}, + /* v */ {0,0,17,17,17,10,4,0}, + /* w */ {0,0,17,17,21,21,30,0}, + /* x */ {0,0,17,10,4,10,17,0}, + /* y */ {0,0,17,17,17,30,16,15}, + /* z */ {0,0,31,8,4,2,31,0}, + /* { */ {12,2,2,1,2,2,12,0}, + /* | */ {1,1,1,0,1,1,1,0}, + /* } */ {3,4,4,8,4,4,3,0}, + /* ~ */ {38,25,0,0,0,0,0,0}, + /* ⌂ */ {0,0,4,10,17,17,31,0}, + /* Ç */ {14,17,1,1,17,14,16,12}, + /* ü */ {10,0,17,17,17,17,30,0}, + /* é */ {24,0,14,17,31,1,30,0}, + /* â */ {14,17,14,16,30,17,30,0}, + /* ä */ {10,0,14,16,30,17,30,0}, + /* à */ {3,0,14,16,30,17,30,0}, + /* å */ {4,0,14,16,30,17,30,0}, + /* ç */ {0,14,17,1,17,14,16,12}, + /* ê */ {14,17,14,17,31,1,30,0}, + /* ë */ {10,0,14,17,31,1,30,0}, + /* è */ {3,0,14,17,31,1,30,0}, + /* ï */ {5,0,2,2,2,2,2,0}, + /* î */ {14,17,4,4,4,4,4,0}, + /* ì */ {3,0,2,2,2,2,2,0}, + /* Ä */ {17,14,17,31,17,17,17,0}, + /* Å */ {4,0,14,17,31,17,17,0}, + /* É */ {24,0,31,1,7,1,31,0}, + /* æ */ {0,0,10,20,30,5,30,0}, + /* Æ */ {30,5,15,5,5,5,29,0}, + /* ô */ {14,17,14,17,17,17,14,0}, + /* ö */ {10,0,14,17,17,17,14,0}, + /* ò */ {3,0,14,17,17,17,14,0}, + /* û */ {14,17,0,17,17,17,30,0}, + /* ù */ {3,0,17,17,17,17,30,0}, + /* ÿ */ {10,0,17,17,17,30,16,15}, + /* Ö */ {17,14,17,17,17,17,14,0}, + /* Ü */ {17,0,17,17,17,17,14,0}, + /* ø */ {0,0,14,25,21,19,14,4}, + /* £ */ {12,18,2,15,2,2,31,0}, + /* Ø */ {14,17,25,21,19,17,14,0}, + /* × */ {0,0,5,2,5,0,0,0}, + /* ƒ */ {8,20,4,14,4,4,5,2}, + /* á */ {24,0,14,16,30,17,30,0}, + /* í */ {3,0,1,1,1,1,1,0}, + /* ó */ {24,0,14,17,17,17,14,0}, + /* ú */ {24,0,17,17,17,17,30,0}, + /* ñ */ {31,0,15,17,17,17,17,0}, + /* Ñ */ {31,0,17,19,21,25,17,0}, + /* ª */ {14,16,31,30,0,31,0,0}, + /* º */ {14,17,17,14,0,31,0,0}, + /* ¿ */ {4,0,4,2,1,17,14,0}, + /* ® */ {0,30,45,37,43,30,0,0}, + /* ¬ */ {0,0,0,31,16,16,0,0}, + /* ½ */ {17,9,8,4,18,10,25,0}, + /* ¼ */ {17,9,8,4,26,26,17,0}, + /* ¡ */ {0,1,0,1,1,1,1,0}, + /* « */ {0,20,10,5,10,20,0,0}, + /* » */ {0,5,10,20,10,5,0,0}, + /* 176 */ {68,17,68,17,68,17,68,17}, + /* 177 */ {170,85,170,85,170,85,170,85}, + /* 178 */ {219,238,219,119,219,238,219,119}, + /* 179 */ {24,24,24,24,24,24,24,24}, + /* 180 */ {24,24,24,24,31,24,24,24}, + /* 181 */ {24,24,31,24,31,24,24,24}, + /* 182 */ {108,108,108,108,111,108,108,108}, + /* 183 */ {0,0,0,0,127,108,108,108}, + /* 184 */ {0,0,31,24,31,24,24,24}, + /* 185 */ {108,108,111,96,111,108,108,108}, + /* 186 */ {108,108,108,108,108,108,108,108}, + /* 187 */ {0,0,127,96,111,108,108,108}, + /* 188 */ {108,108,111,96,127,0,0,0}, + /* 189 */ {108,108,108,108,127,0,0,0}, + /* 190 */ {24,24,31,24,31,0,0,0}, + /* 191 */ {0,0,0,0,31,24,24,24}, + /* 192 */ {24,24,24,24,248,0,0,0}, + /* 193 */ {24,24,24,24,255,0,0,0}, + /* 194 */ {0,0,0,0,255,24,24,24}, + /* 195 */ {24,24,24,24,248,24,24,24}, + /* 196 */ {0,0,0,0,255,0,0,0}, + /* 197 */ {24,24,24,24,255,24,24,24}, + /* 198 */ {24,24,248,24,248,24,24,24}, + /* 199 */ {108,108,108,108,236,108,108,108}, + /* 200 */ {108,108,236,12,252,0,0,0}, + /* 201 */ {0,0,252,12,236,108,108,108}, + /* 202 */ {108,108,239,0,255,0,0,0}, + /* 203 */ {0,0,255,0,239,108,108,108}, + /* 204 */ {108,108,236,12,236,108,108,108}, + /* 205 */ {0,0,255,0,255,0,0,0}, + /* 206 */ {108,108,239,0,239,108,108,108}, + /* 207 */ {24,24,255,0,255,0,0,0}, + /* 208 */ {108,108,108,108,255,0,0,0}, + /* 209 */ {0,0,255,0,255,24,24,24}, + /* 210 */ {0,0,0,0,255,108,108,108}, + /* 211 */ {108,108,108,108,252,0,0,0}, + /* 212 */ {24,24,248,24,248,0,0,0}, + /* 213 */ {0,0,248,24,248,24,24,24}, + /* 214 */ {0,0,0,0,252,108,108,108}, + /* 215 */ {108,108,108,108,255,108,108,108}, + /* 216 */ {24,24,255,24,255,24,24,24}, + /* 217 */ {24,24,24,24,31,0,0,0}, + /* 218 */ {0,0,0,0,248,24,24,24}, + /* 219 */ {255,255,255,255,255,255,255,255}, + /* 220 */ {0,0,0,0,255,255,255,255}, + /* 221 */ {15,15,15,15,15,15,15,15}, + /* 222 */ {240,240,240,240,240,240,240,240}, + /* 223 */ {255,255,255,255,0,0,0,0}, + /* 224 */ {0,0,110,59,19,59,110,0}, + /* 225 */ {0,30,51,31,51,31,3,3}, + /* 226 */ {0,63,51,3,3,3,3,0}, + /* 227 */ {0,127,54,54,54,54,54,0}, + /* 228 */ {63,51,6,12,6,51,63,0}, + /* 229 */ {0,0,126,27,27,27,14,0}, + /* 230 */ {0,102,102,102,102,62,6,3}, + /* 231 */ {0,110,59,24,24,24,24,0}, + /* 232 */ {63,12,30,51,51,30,12,63}, + /* 233 */ {28,54,99,127,99,54,28,0}, + /* 234 */ {28,54,99,99,54,54,119,0}, + /* 235 */ {56,12,24,62,51,51,30,0}, + /* 236 */ {0,0,126,219,219,126,0,0}, + /* 237 */ {96,48,126,219,219,126,6,3}, + /* 238 */ {28,6,3,31,3,6,28,0}, + /* 239 */ {30,51,51,51,51,51,51,0}, + /* 240 */ {0,63,0,63,0,63,0,0}, + /* 241 */ {12,12,63,12,12,0,63,0}, + /* 242 */ {6,12,24,12,6,0,63,0}, + /* 243 */ {24,12,6,12,24,0,63,0}, + /* 244 */ {112,216,216,24,24,24,24,24}, + /* 245 */ {24,24,24,24,24,27,27,14}, + /* 246 */ {12,12,0,63,0,12,12,0}, + /* 247 */ {0,110,59,0,110,59,0,0}, + /* 248 */ {28,54,54,28,0,0,0,0}, + /* 249 */ {0,0,0,24,24,0,0,0}, + /* 250 */ {0,0,0,0,24,0,0,0}, + /* 251 */ {240,48,48,48,55,54,60,56}, + /* 252 */ {30,54,54,54,54,0,0,0}, + /* 253 */ {14,24,12,6,30,0,0,0}, + /* 254 */ {0,0,60,60,60,60,0,0}, + /* 255 */ {0,0,0,0,0,0,0,0}, + }; + + /** + * A static non-malleable MinecraftFont. + */ + public static final MinecraftFont Font = new MinecraftFont(false); + + /** + * Initialize a new MinecraftFont. + */ + public MinecraftFont() { + this(true); + } + + private MinecraftFont(boolean malleable) { + for (int i = 1; i < fontData.length; ++i) { + char ch = (char) i; + if (i >= 32 && i < 32 + fontChars.length()) { + ch = fontChars.charAt(i - 32); + } + + if (ch == ' ') { + setChar(ch, new CharacterSprite(spaceSize, 8, new boolean[spaceSize * 8])); + continue; + } + + int[] rows = fontData[i]; + int width = 0; + for (int r = 0; r < 8; ++r) { + for (int c = 0; c < 8; ++c) { + if ((rows[r] & (1 << c)) != 0 && c > width) { + width = c; + } + } + } + ++width; + + boolean[] data = new boolean[width * 8]; + for (int r = 0; r < 8; ++r) { + for (int c = 0; c < width; ++c) { + data[r * width + c] = (rows[r] & (1 << c)) != 0; + } + } + + setChar(ch, new CharacterSprite(width, 8, data)); + } + + this.malleable = malleable; + } + +} diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java index 846aeb89..e209b718 100644 --- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java @@ -562,6 +562,13 @@ public final class JavaPluginLoader implements PluginLoader { ((ServerListener) listener).onServerCommand((ServerCommandEvent) event); } }; + + case MAP_INITIALIZE: + return new EventExecutor() { + public void execute(Listener listener, Event event) { + ((ServerListener) listener).onMapInitialize((MapInitializeEvent) event); + } + }; // World Events case CHUNK_LOAD: -- cgit v1.2.3