diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansDisplay.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansDisplay.java index 4e346e626..1d0003b48 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansDisplay.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansDisplay.java @@ -251,18 +251,4 @@ public class ClansDisplay extends MiniPlugin else if (Clans.getClanUtility().isChunkHome(owner, chunk)) return "" + C.xEnemy + "H"; else return "" + C.xEnemy + "#"; } - - public void handleInteract(PlayerInteractEvent event) - { - if (event.getPlayer().getItemInHand().getType() != Material.MAP) - return; - - if (!Recharge.Instance.use(event.getPlayer(), "Clan Map", 500, false, false)) - return; - - displayOwner(event.getPlayer()); - displayMap(event.getPlayer()); - } - - } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java index 7bd7b43bd..95b6220d5 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java @@ -40,6 +40,7 @@ import mineplex.game.clans.clans.commands.ClansAllyChatCommand; import mineplex.game.clans.clans.commands.ClansChatCommand; import mineplex.game.clans.clans.commands.ClansCommand; import mineplex.game.clans.clans.commands.ServerTimeCommand; +import mineplex.game.clans.clans.map.ItemMapManager; import mineplex.game.clans.clans.regions.ClansRegions; import mineplex.game.clans.clans.repository.ClanTerritory; import mineplex.game.clans.clans.repository.tokens.ClanMemberToken; @@ -95,6 +96,7 @@ public class ClansManager extends MiniClientPlugin implements IRelat private ProjectileManager _projectileManager; private WorldEventManager _worldEvent; private Chat _chat; + private ItemMapManager _itemMapManager; private int _inviteExpire = 2; private int _nameMin = 3; @@ -131,6 +133,7 @@ public class ClansManager extends MiniClientPlugin implements IRelat _clanDisplay = new ClansDisplay(plugin, this); _clanGame = new ClansGame(plugin, this); _clanUtility = new ClansUtility(this); + _itemMapManager = new ItemMapManager(this); Energy energy = new Energy(plugin); PacketHandler packetHandler = new PacketHandler(plugin); @@ -204,6 +207,11 @@ public class ClansManager extends MiniClientPlugin implements IRelat addCommand(new ClanManagementCommand(this)); } + public ItemMapManager getItemMapManager() + { + return _itemMapManager; + } + public int getInviteExpire() { return _inviteExpire; @@ -301,7 +309,6 @@ public class ClansManager extends MiniClientPlugin implements IRelat public void Interact(PlayerInteractEvent event) { getClanGame().Interact(event); - getClanDisplay().handleInteract(event); } @EventHandler diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java index a0ade1b89..99242e044 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java @@ -1045,20 +1045,7 @@ public class ClansCommand extends CommandBase public void map(Player caller, String[] args) { - if (args.length > 1) - { - if (args[1].equals("toggle") || args[1].equals("t")) - { - Plugin.Get(caller).setMapOn(!Plugin.Get(caller).isMapOn()); - UtilPlayer.message(caller, - F.main("Clans", "You toggled Clan Map: " + F.oo(Plugin.Get(caller).isMapOn()))); - return; - } - } - - //Display - Plugin.getClanDisplay().displayOwner(caller); - Plugin.getClanDisplay().displayMap(caller); + Plugin.getItemMapManager().setMap(caller); } public void home(Player caller, String[] args) diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java new file mode 100644 index 000000000..05735b2c4 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapManager.java @@ -0,0 +1,836 @@ +package mineplex.game.clans.clans.map; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; + +import mineplex.core.MiniPlugin; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTextBottom; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClansUtility; +import net.minecraft.server.v1_7_R4.Block; +import net.minecraft.server.v1_7_R4.Blocks; +import net.minecraft.server.v1_7_R4.MaterialMapColor; +import net.minecraft.util.com.google.common.collect.HashMultiset; +import net.minecraft.util.com.google.common.collect.Iterables; +import net.minecraft.util.com.google.common.collect.Multisets; +import net.minecraft.util.org.apache.commons.io.FileUtils; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_7_R4.CraftChunk; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.map.MapRenderer; +import org.bukkit.map.MapView; + +public class ItemMapManager extends MiniPlugin +{ + private int _blocksScan = 16 * 12; + private ClansUtility _clansUtility; + private Comparator> _comparator; + private int _halfMapSize = 1536 / 2; + private int[][] _heightMap = new int[(_halfMapSize * 2) + 16][]; + private boolean _loadWorld = true; + private HashMap _map = new HashMap(); + private short _mapId = -1; + private HashMap _mapInfo = new HashMap(); + private HashMap _scale = new HashMap(); + private ArrayList> _scanList = new ArrayList>(); + private World _world; + + public ItemMapManager(ClansManager clansManager) + { + super("ItemMapManager", clansManager.getPlugin()); + + _clansUtility = clansManager.getClanUtility(); + + _comparator = new Comparator>() + { + + @Override + public int compare(Entry o1, Entry o2) + { + // Render the places outside the map first to speed up visual errors fixing + int outsideMap = Boolean.compare(o1.getValue() < -_halfMapSize, o2.getValue() < -_halfMapSize); + + if (outsideMap != 0) + { + return -outsideMap; + } + + double dist1 = 0; + double dist2 = 0; + + for (Player player : UtilServer.getPlayers()) + { + dist1 += getDistance(o1, player.getLocation().getX(), player.getLocation().getZ()); + dist2 += getDistance(o2, player.getLocation().getX(), player.getLocation().getZ()); + } + + if (dist1 != dist2) + { + return Double.compare(dist1, dist2); + } + + dist1 = getDistance(o1, 0, 0); + dist2 = getDistance(o2, 0, 0); + + return Double.compare(dist1, dist2); + + } + }; + + for (int x = -_halfMapSize; x < _halfMapSize; x += _blocksScan) + { + for (int z = -_halfMapSize - 16; z < _halfMapSize; z += (z < -_halfMapSize ? 16 : _blocksScan)) + { + _scanList.add(new HashMap.SimpleEntry(x, z)); + } + } + + _scale.put(0, 1); + // _scale.put(1, 2); + _scale.put(1, 4); + _scale.put(2, 8); + _scale.put(3, 13); + // _scale.put(5, 16); + + for (Entry entry : _scale.entrySet()) + { + int size = (_halfMapSize * 2) / entry.getValue(); + Byte[][] bytes = new Byte[size][]; + + for (int i = 0; i < size; i++) + { + bytes[i] = new Byte[size]; + } + + _map.put(entry.getKey(), bytes); + } + + for (int i = 0; i < _heightMap.length; i++) + { + _heightMap[i] = new int[_heightMap.length]; + } + + _world = Bukkit.getWorld("world"); + + MapView view = null; + + try + { + File file = new File("world/clans_map_id"); + + if (file.exists()) + { + BufferedReader br = new BufferedReader(new FileReader(file)); + _mapId = Short.parseShort(br.readLine()); + br.close(); + + File file1 = new File("world/data/map_" + _mapId); + + if (!file1.exists()) + { + boolean copied = false; + + for (File f : file1.getParentFile().listFiles()) + { + if (f.getName().contains("map_")) + { + FileUtils.copyFile(f, file1); + copied = true; + } + } + + if (!copied) + { + _mapId = -1; + file.delete(); + } + } + + view = Bukkit.getMap(_mapId); + } + + if (_mapId < 0) + { + view = Bukkit.createMap(_world); + _mapId = view.getId(); + + file.createNewFile(); + + PrintWriter writer = new PrintWriter(file, "UTF-8"); + writer.print(_mapId); + writer.close(); + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + + for (MapRenderer renderer : view.getRenderers()) + { + view.removeRenderer(renderer); + } + + view.addRenderer(new ItemMapRenderer(this)); + + rebuildScan(); + } + + @EventHandler + public void dropItem(ItemSpawnEvent event) + { + ItemStack item = event.getEntity().getItemStack(); + + if (item != null && item.getType() == Material.MAP && item.getDurability() == _mapId) + { + event.getEntity().remove(); + } + } + + @EventHandler + public void recenterMap(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + { + return; + } + + for (Player player : Bukkit.getOnlinePlayers()) + { + MapInfo info = getMap(player); + + if (info.getScale() >= 3) + { + continue; + } + + Location l = player.getLocation(); + int zoom = getZoom(info.getScale()); + + double mapX = (l.getX() - info.getX()) / zoom; + double mapZ = (l.getZ() - info.getZ()) / zoom; + + if (Math.abs(mapX) > 22 || Math.abs(mapZ) > 22) + { + int newX = calcMapCenter(zoom, l.getBlockX()); + int newZ = calcMapCenter(zoom, l.getBlockZ()); + + if (Math.abs(mapX) > 22 ? newX != info.getX() : newZ != info.getZ()) + { + info.setInfo(newX, newZ); + } + } + } + } + + /** + * Get the center of the map. + */ + public int calcMapCenter(int zoom, int cord) + { + int mapSize = _halfMapSize / zoom; // This is how large the map is in pixels + + int mapCord = cord / zoom; // This is pixels from true center of map, not held map + + int fDiff = mapSize - -mapCord; + int sDiff = mapSize - mapCord; + + double chunkBlock = cord & 0xF; + cord -= chunkBlock; + chunkBlock /= zoom; + + /*if ((fDiff < 64 || sDiff < 64) && (Math.abs(fDiff - sDiff) > 1)) + { + cord += (fDiff > sDiff ? Math.floor(chunkBlock) : Math.ceil(chunkBlock)); + } + else*/ + { + cord += (int) Math.floor(chunkBlock) * zoom; + } + + while ((fDiff < 64 || sDiff < 64) && (Math.abs(fDiff - sDiff) > 1)) + { + int change = (fDiff > sDiff ? -zoom : zoom); + cord += change; + + mapCord = cord / zoom; + + fDiff = mapSize - -mapCord; + sDiff = mapSize - mapCord; + } + + return cord; + } + + private void colorWorldHeight(int scale, int startingX, int startingZ) + { + Byte[][] map = _map.get(scale); + int zoom = getZoom(scale); + + for (int x = startingX; x < startingX + _blocksScan; x += zoom) + { + double d0 = 0; + + // Prevents ugly lines for the first line of Z + + for (int addX = 0; addX < zoom; addX++) + { + for (int addZ = 0; addZ < zoom; addZ++) + { + int hX = x + addX + _halfMapSize; + int hZ = (startingZ - zoom) + addZ + _halfMapSize; + + if (hX >= _halfMapSize * 2 || hZ >= _halfMapSize * 2) + { + continue; + } + + d0 += _heightMap[hX + 16][hZ + 16] / (zoom * zoom); + } + } + + for (int z = startingZ; z < startingZ + _blocksScan; z += zoom) + { + // Water depth colors not included + double d1 = 0; + + for (int addX = 0; addX < zoom; addX++) + { + for (int addZ = 0; addZ < zoom; addZ++) + { + int hX = x + addX + _halfMapSize; + int hZ = z + addZ + _halfMapSize; + + if (hX >= _halfMapSize * 2 || hZ >= _halfMapSize * 2) + { + continue; + } + + d1 += _heightMap[hX + 16][hZ + 16] / (zoom * zoom); + } + } + + double d2 = (d1 - d0) * 4.0D / (zoom + 4) + ((x + z & 0x1) - 0.5D) * 0.4D; + byte b0 = 1; + + d0 = d1; + + if (d2 > 0.6D) + { + b0 = 2; + } + else if (d2 > 1.2D) + { + b0 = 3; + } + else if (d2 < -0.6D) + { + b0 = 0; + } + + int origColor = map[(x + _halfMapSize) / zoom][(z + _halfMapSize) / zoom] - 1; + + /*if (color < 4) + { + d2 = waterDepth * 0.1D + (k1 + j2 & 0x1) * 0.2D; + b0 = 1; + if (d2 < 0.5D) + { + b0 = 2; + } + + if (d2 > 0.9D) + { + b0 = 0; + } + }*/ + + byte color = (byte) (origColor + b0); + map[(x + _halfMapSize) / zoom][(z + _halfMapSize) / zoom] = color; + } + } + } + + public void scanWorldMap(int startingX, int startingZ, boolean setColors) + { + Byte[][] map = _map.get(0); + + for (int beginX = startingX; beginX < startingX + _blocksScan; beginX += 16) + { + for (int beginZ = startingZ - (startingZ > -_halfMapSize ? 16 : 0); beginZ < startingZ + + (setColors ? _blocksScan : 16); beginZ += 16) + { + Chunk chunk = _world.getChunkAt(beginX / 16, beginZ / 16); + boolean loaded = false; + + if (!chunk.isLoaded()) + { + if (_loadWorld) + { + loaded = chunk.load(); + } + else + { + continue; + } + } + + net.minecraft.server.v1_7_R4.Chunk nmsChunk = ((CraftChunk) chunk).getHandle(); + + for (int x = beginX; x < beginX + 16; x++) + { + for (int z = beginZ; z < beginZ + 16; z++) + { + int color = 0; + + if (!nmsChunk.isEmpty()) + { + int k3 = x & 0xF; + int l3 = z & 0xF; + + int l4 = nmsChunk.b(k3, l3) + 1; + Block block = Blocks.AIR; + int i5 = 0; + + if (l4 > 1) + { + do + { + l4--; + block = nmsChunk.getType(k3, l4, l3); + i5 = nmsChunk.getData(k3, l4, l3); + } + while ((block.f(i5) == MaterialMapColor.b) && (l4 > 0)); + + if ((l4 > 0) && (block.getMaterial().isLiquid())) + { + int j5 = l4 - 1; + Block block1; + do + { + block1 = nmsChunk.getType(k3, j5--, l3); + } + while ((j5 > 0) && (block1.getMaterial().isLiquid())); + } + } + + _heightMap[x + _halfMapSize + 16][z + _halfMapSize + 16] = l4; + + if (setColors) + { + color = block.f(i5).M; + + color = (byte) ((color * 4) + 1); + } + } + + if (setColors && beginZ >= startingZ) + { + map[x + _halfMapSize][z + _halfMapSize] = (byte) color; + } + } + + if (loaded) + { + chunk.unload(); + } + } + } + } + } + + private void drawWorldScale(int scale, int startingX, int startingZ) + { + Byte[][] first = _map.get(0); + Byte[][] second = _map.get(scale); + int zoom = getZoom(scale); + + for (int x = startingX; x < startingX + _blocksScan; x += zoom) + { + for (int z = startingZ; z < startingZ + _blocksScan; z += zoom) + { + HashMultiset hashmultiset = HashMultiset.create(); + + for (int addX = 0; addX < zoom; addX++) + { + for (int addZ = 0; addZ < zoom; addZ++) + { + int pX = x + addX + _halfMapSize; + int pZ = z + addZ + _halfMapSize; + + if (pX >= first.length || pZ >= first.length) + { + continue; + } + + Byte b = first[pX][pZ]; + + hashmultiset.add(b); + } + } + + Byte color = Iterables.getFirst(Multisets.copyHighestCountFirst(hashmultiset), (byte) 0); + + second[(x + _halfMapSize) / zoom][(z + _halfMapSize) / zoom] = color; + } + } + } + + public ClansUtility getClansUtility() + { + return _clansUtility; + } + + private double getDistance(double x1, double z1, double x2, double z2) + { + x1 = (x1 - x2); + z1 = (z1 - z2); + + return (x1 * x1) + (z1 * z1); + } + + private double getDistance(Entry entry, double x1, double z1) + { + return getDistance(x1, z1, entry.getKey() + (_blocksScan / 2), entry.getValue() + (_blocksScan / 2)); + } + + public Byte[][] getMap(int scale) + { + return _map.get(scale); + } + + public MapInfo getMap(Player player) + { + return _mapInfo.get(player.getName()); + } + + public short getMapId() + { + return _mapId; + } + + public int getMapSize() + { + return _halfMapSize; + } + + public int getZoom(int scale) + { + return _scale.get(scale); + } + + @EventHandler + public void onInteract(PlayerInteractEvent event) + { + if (event.getAction() == Action.PHYSICAL) + return; + + ItemStack item = event.getItem(); + + if (item == null || item.getType() != Material.MAP || item.getDurability() != _mapId) + return; + + Player player = event.getPlayer(); + + MapInfo info = _mapInfo.get(player.getName()); + + boolean zoomIn = event.getAction().name().contains("LEFT"); + + if (!_scale.containsKey(info.getScale() + (zoomIn ? -1 : 1))) + { + return; + } + + if (!info.canZoom()) + { + long remainingTime = (info.getZoomCooldown() + 2500) - System.currentTimeMillis(); + + UtilPlayer.message( + player, + F.main("Recharge", + "You cannot use " + F.skill("Map Zoom") + " for " + + F.time(UtilTime.convertString((remainingTime), 1, TimeUnit.FIT)) + ".")); + return; + } + + info.addZoom(); + + if (zoomIn) + { + int newScale = info.getScale() - 1; + Location loc = player.getLocation(); + + int zoom = getZoom(newScale); + + info.setInfo(newScale, calcMapCenter(zoom, loc.getBlockX()), calcMapCenter(zoom, loc.getBlockZ())); + } + else + { + int newScale = info.getScale() + 1; + Location loc = player.getLocation(); + + int zoom = getZoom(newScale); + + info.setInfo(newScale, calcMapCenter(zoom, loc.getBlockX()), calcMapCenter(zoom, loc.getBlockZ())); + } + + showZoom(player, info); + } + + private void showZoom(Player player, MapInfo info) + { + String progressBar = C.cBlue + ""; + + boolean colorChange = false; + + for (int i = 2; i >= 0; i--) + { + if (!colorChange && i < info.getScale()) + { + progressBar += C.cGray; + colorChange = true; + } + + char c; + + switch (i) + { + case 0: + c = '█'; + break; + case 1: + c = '▆'; + break; + default: + c = '▄'; + break; + } + + for (int a = 0; a < 4; a++) + { + progressBar += c; + } + + if (i > 0) + { + progressBar += " "; + } + } + + UtilTextBottom.display(progressBar, player); + } + + @EventHandler + public void onHotbarMove(PlayerItemHeldEvent event) + { + Player player = event.getPlayer(); + + ItemStack item = player.getInventory().getItem(event.getNewSlot()); + + if (item == null || item.getType() != Material.MAP || item.getDurability() != _mapId) + return; + + showZoom(player, getMap(player)); + + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) + { + MapInfo info = new MapInfo(); + + Player player = event.getPlayer(); + Location loc = player.getLocation(); + + int zoom = getZoom(1); + + info.setInfo(1, calcMapCenter(zoom, loc.getBlockX()), calcMapCenter(zoom, loc.getBlockZ())); + _mapInfo.put(player.getName(), info); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) + { + _mapInfo.remove(event.getPlayer().getName()); + } + + private void rebuildScan() + { + for (int x = -_halfMapSize; x < _halfMapSize; x += _blocksScan) + { + for (int z = -_halfMapSize - 16; z < _halfMapSize; z += (z < -_halfMapSize ? 16 : _blocksScan)) + { + _scanList.add(new HashMap.SimpleEntry(x, z)); + } + } + + if (!_loadWorld) + { + Iterator> itel = _scanList.iterator(); + + while (itel.hasNext()) + { + Entry entry = itel.next(); + boolean removeEntry = true; + + for (Player player : UtilServer.getPlayers()) + { + if (Math.sqrt(getDistance(entry, player.getLocation().getX(), player.getLocation().getZ())) < 200) + { + removeEntry = false; + break; + } + } + + if (removeEntry) + { + itel.remove(); + } + } + } + + Collections.sort(_scanList, _comparator); + } + + @EventHandler + public void renderMap(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + { + return; + } + + if (_scanList.isEmpty()) + { + if (_loadWorld) + { + for (int x = -_halfMapSize; x < _halfMapSize; x += _blocksScan) + { + for (int z = -_halfMapSize; z < _halfMapSize; z += _blocksScan) + { + drawWorldScale(3, x, z); + colorWorldHeight(3, x, z); + } + } + + System.out.print("Finished first map scan and render"); + } + + _loadWorld = false; + + if (UtilServer.getPlayers().length == 0) + return; + + rebuildScan(); + } + else if (_scanList.size() % 20 == 0) + { + Collections.sort(_scanList, _comparator); + } + + Entry entry = _scanList.remove(0); + + int startingX = entry.getKey(); + int startingZ = entry.getValue(); + + boolean outsideMap = startingZ < -_halfMapSize; + + scanWorldMap(startingX, startingZ, !outsideMap); + + if (outsideMap) + { + return; + } + + for (int scale = 1; scale < _scale.size(); scale++) + { + if (scale == 3 && _loadWorld) + continue; + + if (!outsideMap) + { + drawWorldScale(scale, startingX, startingZ); + } + + colorWorldHeight(scale, startingX, startingZ); + } + + colorWorldHeight(0, startingX, startingZ); + } + + @EventHandler + public void mapMoveInventories(InventoryClickEvent event) + { + ItemStack item = event.getCurrentItem(); + + if (item == null || item.getType() != Material.MAP || item.getDurability() != _mapId) + return; + + if (event.getClickedInventory() == null || event.getClickedInventory().getHolder() instanceof Player) + return; + + event.setCancelled(true); + + UtilPlayer.message(event.getWhoClicked(), + F.main("Inventory", "You cannot move " + F.item("Clans Map") + " between inventories.")); + } + + public void setMap(Player player) + { + for (ItemStack item : UtilInv.getItems(player)) + { + if (item.getType() == Material.MAP && item.getDurability() == _mapId) + { + return; + } + } + + ItemStack item = new ItemStack(Material.MAP, 1, _mapId); + + int slot = player.getInventory().firstEmpty(); + + if (slot >= 0) + { + ItemStack mapSlot = player.getInventory().getItem(8); + + if (mapSlot == null || mapSlot.getType() == Material.AIR) + { + slot = 8; + } + + player.getInventory().setItem(slot, item); + } + } + +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapRenderer.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapRenderer.java new file mode 100644 index 000000000..bc70b68fe --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/ItemMapRenderer.java @@ -0,0 +1,238 @@ +package mineplex.game.clans.clans.map; + +import java.awt.Color; +import mineplex.core.common.util.UtilTime; +import mineplex.game.clans.clans.ClanInfo; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.map.MapCanvas; +import org.bukkit.map.MapCursor; +import org.bukkit.map.MapCursorCollection; +import org.bukkit.map.MapPalette; +import org.bukkit.map.MapRenderer; +import org.bukkit.map.MapView; + +public class ItemMapRenderer extends MapRenderer +{ + private ItemMapManager _manager; + + public ItemMapRenderer(ItemMapManager itemMapManager) + { + super(true); + + _manager = itemMapManager; + } + + @Override + public void render(MapView mapView, MapCanvas canvas, Player player) + { + MapInfo info = _manager.getMap(player); + + if (info == null) + { + return; + } + + int scale = info.getScale(); + int zoom = _manager.getZoom(scale); + + ClanInfo clan = _manager.getClansUtility().getClanByPlayer(player); + + Byte[][] map = _manager.getMap(scale); + + int centerX = info.getX() / zoom; + int centerZ = info.getZ() / zoom; + + // We have this cooldown to squeeze out every single bit of performance from the server. + if (UtilTime.elapsed(info.getLastRendered(), 4000)) + { + info.setLastRendered(); + + for (int mapX = 0; mapX < 128; mapX++) + { + for (int mapZ = 0; mapZ < 128; mapZ++) + { + int blockX = centerX + (mapX - 64); + int blockZ = centerZ + (mapZ - 64); + + int pixelX = blockX + (map.length / 2); + int pixelZ = blockZ + (map.length / 2); + + Byte color; + + if (!(pixelX < 0 || pixelZ < 0 || pixelX >= map.length || pixelZ >= map.length) + && map[pixelX][pixelZ] != null) + { + + color = map[pixelX][pixelZ]; + + blockX *= zoom; + blockZ *= zoom; + + String chunk = "world," + (int) Math.floor(blockX / 16D) + "," + (int) Math.floor(blockZ / 16D); + + ClanInfo owningClan = _manager.getClansUtility().getOwner(chunk); + + if (owningClan != null) + { + Color clanColor = null; + + if (owningClan == clan) + { + clanColor = Color.CYAN; + } + else + { + if (owningClan.isAdmin()) + { + if (owningClan.getName().equals("Shops") || owningClan.getName().equals("Spawn")) + { + clanColor = Color.WHITE; + } + else + { + clanColor = Color.GRAY; + } + } + else if (clan == null) + { + clanColor = Color.YELLOW; + } + else if (owningClan.hasEnemy() && owningClan.getEnemyData().getEnemyName().equals(clan.getName())) + { + clanColor = Color.RED; + } + else if (clan.isAlly(owningClan.getName())) + { + clanColor = Color.GREEN; + } + else if (clan.isNeutral(owningClan.getName())) + { + clanColor = Color.YELLOW; + } + } + + if (clanColor != null) + { + int chunkBX = blockX & 0xF; + int chunkBZ = blockZ & 0xF; + int chunkX1 = (int) Math.floor(blockX / 16D); + int chunkZ1 = (int) Math.floor(blockZ / 16D); + + if ( + + ((chunkBX == 0 || zoom == 13) && + + owningClan != _manager.getClansUtility().getOwner("world," + (chunkX1 - 1) + "," + chunkZ1)) + + || ((chunkBZ == 0 || zoom == 13) && + + owningClan != _manager.getClansUtility().getOwner("world," + chunkX1 + "," + (chunkZ1 - 1))) + + || ((chunkBX + zoom > 15 || zoom == 13) && + + owningClan != _manager.getClansUtility().getOwner("world," + (chunkX1 + 1) + "," + chunkZ1)) + + || ((chunkBZ + zoom > 15 || zoom == 13) && + + owningClan != _manager.getClansUtility().getOwner("world," + chunkX1 + "," + (chunkZ1 + 1)))) + { + Color cColor = MapPalette.getColor(color); + double clans = 0.65; + double base = 1 - clans; + + int r = (int) ((cColor.getRed() * base) + (clanColor.getRed() * clans)); + int b = (int) ((cColor.getBlue() * base) + (clanColor.getBlue() * clans)); + int g = (int) ((cColor.getGreen() * base) + (clanColor.getGreen() * clans)); + + color = MapPalette.matchColor(r, g, b); + } + else + { + Color cColor = MapPalette.getColor(color); + + double clans = 0.4; + double base = 1 - clans; + + int r = (int) ((cColor.getRed() * base) + (clanColor.getRed() * clans)); + int b = (int) ((cColor.getBlue() * base) + (clanColor.getBlue() * clans)); + int g = (int) ((cColor.getGreen() * base) + (clanColor.getGreen() * clans)); + + color = MapPalette.matchColor(r, g, b); + } + } + } + } + else + { + color = (byte) 0; + } + + canvas.setPixel(mapX, mapZ, color); + } + } + } + + if (info.isSendMap()) + { + player.sendMap(mapView); + } + + MapCursorCollection cursors = canvas.getCursors(); + + while (cursors.size() > 0) + { + cursors.removeCursor(cursors.getCursor(0)); + } + + for (Player other : Bukkit.getOnlinePlayers()) + { + if (player.canSee(other)) + { + Location l = other.getLocation(); + + double mapX = (l.getX() - info.getX()) / zoom; + double mapZ = (l.getZ() - info.getZ()) / zoom; + + if (mapX > -64 && mapX < 64 && mapZ > -64 && mapZ < 64) + { + ClanInfo otherClan = _manager.getClansUtility().getClanByPlayer(other); + + MapCursor.Type cursorDisplay; + + if (player == other) + { + cursorDisplay = MapCursor.Type.WHITE_POINTER; + } + else if (otherClan == null || clan == null) + { + continue; + } + else if (otherClan == clan) + { + cursorDisplay = MapCursor.Type.BLUE_POINTER; + } + else if (otherClan.isAlly(clan.getName())) + { + cursorDisplay = MapCursor.Type.GREEN_POINTER; + } + else + { + continue; + } + + byte b0 = (byte) (int) Math.min(127, (double) (mapX * 2.0F) + 0.5D); + byte b1 = (byte) (int) Math.max(-127, (double) (mapZ * 2.0F) + 0.5D); + + byte rotation = (byte) (int) ((l.getYaw() * 16D) / 360D); + + MapCursor cursor = new MapCursor(b0, b1, (byte) (rotation & 0xF), cursorDisplay.getValue(), true); + + cursors.addCursor(cursor); + } + } + } + } +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/MapInfo.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/MapInfo.java new file mode 100644 index 000000000..cf27c628d --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/map/MapInfo.java @@ -0,0 +1,107 @@ +package mineplex.game.clans.clans.map; + +import java.util.ArrayList; +import java.util.Iterator; + +import mineplex.core.common.util.UtilTime; + +public class MapInfo +{ + private int _scale; + private int _centerX; + private int _centerZ; + private long _lastRendered; + private boolean _sendMap; + private ArrayList _lastZooms = new ArrayList(); + + public boolean canZoom() + { + Iterator itel = _lastZooms.iterator(); + + while (itel.hasNext()) + { + long lastZoomed = itel.next(); + + if (UtilTime.elapsed(lastZoomed, 2500)) + { + itel.remove(); + } + } + + return _lastZooms.size() < 3; + } + + public void addZoom() + { + _lastZooms.add(System.currentTimeMillis()); + } + + public long getZoomCooldown() + { + long cooldown = 0; + + for (long zoomCooldown : _lastZooms) + { + if (cooldown == 0 || zoomCooldown < cooldown) + { + cooldown = zoomCooldown; + } + } + + return cooldown; + } + + public long getLastRendered() + { + return _lastRendered; + } + + public void setLastRendered() + { + _lastRendered = System.currentTimeMillis(); + } + + public void setInfo(int scale, int x, int z) + { + _lastRendered = 0; + _scale = scale; + _centerX = x; + _centerZ = z; + _sendMap = true; + } + + public void setInfo(int x, int z) + { + _lastRendered = 0; + _centerX = x; + _centerZ = z; + _sendMap = true; + } + + public boolean isSendMap() + { + if (_sendMap) + { + _sendMap = false; + return true; + } + + return false; + } + + public int getX() + { + return _centerX; + } + + public int getZ() + { + return _centerZ; + } + + public int getScale() + { + return _scale; + } + +}