package org.bukkit.craftbukkit.map; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.map.MapRenderer; import org.bukkit.map.MapView; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; public final class CraftMapView implements MapView { private final Map<CraftPlayer, RenderData> renderCache = new HashMap<CraftPlayer, RenderData>(); public final List<MapRenderer> renderers = new ArrayList<MapRenderer>(); // Spigot private final Map<MapRenderer, Map<CraftPlayer, CraftMapCanvas>> canvases = new HashMap<MapRenderer, Map<CraftPlayer, CraftMapCanvas>>(); protected final net.minecraft.world.storage.MapData worldMap; public CraftMapView(net.minecraft.world.storage.MapData worldMap) { this.worldMap = worldMap; addRenderer(new CraftMapRenderer(this, worldMap)); } public short getId() { String text = worldMap.mapName; if(text.startsWith("map_")) { try { return Short.parseShort(text.substring("map_".length())); } catch(NumberFormatException ex) { throw new IllegalStateException("Map has non-numeric ID"); } } else { throw new IllegalStateException("Map has invalid ID"); } } public boolean isVirtual() { return renderers.size() > 0 && !(renderers.get(0) instanceof CraftMapRenderer); } public Scale getScale() { return Scale.valueOf(worldMap.scale); } public void setScale(Scale scale) { worldMap.scale = scale.getValue(); } public World getWorld() { int dimension = worldMap.dimension; // Cauldron - byte -> int for Forge for(World world : Bukkit.getServer().getWorlds()) { if(((CraftWorld) world).getHandle().provider.dimensionId == dimension) { return world; } } return null; } public void setWorld(World world) { worldMap.dimension = (byte) ((CraftWorld) world).getHandle().provider.dimensionId; } public int getCenterX() { return worldMap.xCenter; } public int getCenterZ() { return worldMap.zCenter; } public void setCenterX(int x) { worldMap.xCenter = x; } public void setCenterZ(int z) { worldMap.zCenter = z; } public List<MapRenderer> getRenderers() { return new ArrayList<MapRenderer>(renderers); } public void addRenderer(MapRenderer renderer) { if(!renderers.contains(renderer)) { renderers.add(renderer); canvases.put(renderer, new HashMap<CraftPlayer, CraftMapCanvas>()); renderer.initialize(this); } } public boolean removeRenderer(MapRenderer renderer) { if(renderers.contains(renderer)) { renderers.remove(renderer); for(Map.Entry<CraftPlayer, CraftMapCanvas> entry : canvases.get(renderer).entrySet()) { for(int x = 0; x < 128; ++x) { for(int y = 0; y < 128; ++y) { entry.getValue().setPixel(x, y, (byte) -1); } } } canvases.remove(renderer); return true; } else { return false; } } private boolean isContextual() { for(MapRenderer renderer : renderers) { if(renderer.isContextual()) return true; } return false; } public RenderData render(CraftPlayer player) { boolean context = isContextual(); RenderData render = renderCache.get(context ? player : null); if(render == null) { render = new RenderData(); renderCache.put(context ? player : null, render); } if(context && renderCache.containsKey(null)) { renderCache.remove(null); } Arrays.fill(render.buffer, (byte) 0); render.cursors.clear(); for(MapRenderer renderer : renderers) { CraftMapCanvas canvas = canvases.get(renderer).get(renderer.isContextual() ? player : null); if(canvas == null) { canvas = new CraftMapCanvas(this); canvases.get(renderer).put(renderer.isContextual() ? player : null, canvas); } canvas.setBase(render.buffer); renderer.render(this, canvas, player); byte[] buf = canvas.getBuffer(); for(int i = 0; i < buf.length; ++i) { byte color = buf[i]; // There are 143 valid color id's, 0 -> 127 and -128 -> -113 if(color >= 0 || color <= -113) render.buffer[i] = color; } for(int i = 0; i < canvas.getCursors().size(); ++i) { render.cursors.add(canvas.getCursors().getCursor(i)); } } return render; } }