Newer
Older
ultramine_bukkit / src / main / java / org / bukkit / craftbukkit / map / CraftMapView.java
@vlad20012 vlad20012 on 24 Feb 2017 4 KB initial
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;
	}

}