1.13 + 1.14 compatibility: the beginning.

- The plugin should be compatible with 1.13+. Compatibility with 1.12- has been dropped; use old versions for them.
- Map IDs are integer instead of shorts now, as the maps limits has been dropped by Minecraft.
- ImageOnMap items are now green to differentiate them. Map parts are lime.
- Removed glow on maps, as zLib's glow effect is not compatible with 1.13+.
This commit is contained in:
Amaury Carrade 2019-10-26 14:26:12 +02:00
parent 4653008e5a
commit fd483d6088
21 changed files with 260 additions and 179 deletions

10
pom.xml
View File

@ -3,13 +3,13 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>fr.moribus</groupId> <groupId>fr.moribus</groupId>
<artifactId>ImageOnMap</artifactId> <artifactId>ImageOnMap</artifactId>
<version>3.1</version> <version>4.0</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
</properties> </properties>
<build> <build>
@ -46,7 +46,7 @@
<repositories> <repositories>
<repository> <repository>
<id>spigot-repo</id> <id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url> <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository> </repository>
<repository> <repository>
<id>zDevelopers</id> <id>zDevelopers</id>
@ -58,7 +58,7 @@
<dependency> <dependency>
<groupId>org.bukkit</groupId> <groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId> <artifactId>bukkit</artifactId>
<version>1.8.3-R0.1-SNAPSHOT</version> <version>1.13.2-R0.1-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>fr.zcraft</groupId> <groupId>fr.zcraft</groupId>

View File

@ -18,13 +18,7 @@
package fr.moribus.imageonmap; package fr.moribus.imageonmap;
import fr.moribus.imageonmap.commands.maptool.DeleteCommand; import fr.moribus.imageonmap.commands.maptool.*;
import fr.moribus.imageonmap.commands.maptool.ExploreCommand;
import fr.moribus.imageonmap.commands.maptool.GetCommand;
import fr.moribus.imageonmap.commands.maptool.GetRemainingCommand;
import fr.moribus.imageonmap.commands.maptool.ListCommand;
import fr.moribus.imageonmap.commands.maptool.MigrateCommand;
import fr.moribus.imageonmap.commands.maptool.NewCommand;
import fr.moribus.imageonmap.image.ImageIOExecutor; import fr.moribus.imageonmap.image.ImageIOExecutor;
import fr.moribus.imageonmap.image.ImageRendererExecutor; import fr.moribus.imageonmap.image.ImageRendererExecutor;
import fr.moribus.imageonmap.image.MapInitEvent; import fr.moribus.imageonmap.image.MapInitEvent;
@ -64,7 +58,7 @@ public final class ImageOnMap extends ZPlugin
public File getImagesDirectory() {return imagesDirectory;} public File getImagesDirectory() {return imagesDirectory;}
public File getMapsDirectory() {return mapsDirectory;} public File getMapsDirectory() {return mapsDirectory;}
public File getImageFile(short mapID) public File getImageFile(int mapID)
{ {
return new File(imagesDirectory, "map"+mapID+".png"); return new File(imagesDirectory, "map"+mapID+".png");
} }
@ -79,7 +73,7 @@ public final class ImageOnMap extends ZPlugin
imagesDirectory = checkPluginDirectory(imagesDirectory, V3Migrator.getOldImagesDirectory(this)); imagesDirectory = checkPluginDirectory(imagesDirectory, V3Migrator.getOldImagesDirectory(this));
checkPluginDirectory(mapsDirectory); checkPluginDirectory(mapsDirectory);
} }
catch(IOException ex) catch(final IOException ex)
{ {
PluginLogger.error("FATAL: " + ex.getMessage()); PluginLogger.error("FATAL: " + ex.getMessage());
this.setEnabled(false); this.setEnabled(false);

View File

@ -74,7 +74,7 @@ public class ListCommand extends IoMCommand
.then(map.getId()) .then(map.getId())
.color(ChatColor.WHITE) .color(ChatColor.WHITE)
.command(GetCommand.class, map.getId()) .command(GetCommand.class, map.getId())
.hover(new ItemStackBuilder(Material.MAP) .hover(new ItemStackBuilder(Material.FILLED_MAP)
.title(ChatColor.GREEN + "" + ChatColor.BOLD + map.getName()) .title(ChatColor.GREEN + "" + ChatColor.BOLD + map.getName())
.lore(ChatColor.GRAY + map.getId() + ", " + size) .lore(ChatColor.GRAY + map.getId() + ", " + size)
.lore("") .lore("")

View File

@ -29,13 +29,9 @@ import fr.zcraft.zlib.components.i18n.I;
import fr.zcraft.zlib.tools.PluginLogger; import fr.zcraft.zlib.tools.PluginLogger;
import fr.zcraft.zlib.tools.items.ItemStackBuilder; import fr.zcraft.zlib.tools.items.ItemStackBuilder;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.material.Dye;
import java.util.Arrays;
import java.util.Random; import java.util.Random;
@ -106,7 +102,7 @@ public class ConfirmDeleteMapGui extends ActionGui
/* ** Item representation of the image being deleted ** */ /* ** Item representation of the image being deleted ** */
action("", 13, new ItemStackBuilder(Material.EMPTY_MAP) action("", 13, new ItemStackBuilder(Material.FILLED_MAP)
/// The title of the map deletion item /// The title of the map deletion item
.title(I.t(getPlayerLocale(), "{red}You're about to destroy this map...")) .title(I.t(getPlayerLocale(), "{red}You're about to destroy this map..."))
/// The end, in the lore, of a title starting with You're about to destroy this map.... /// The end, in the lore, of a title starting with You're about to destroy this map....
@ -134,32 +130,21 @@ public class ConfirmDeleteMapGui extends ActionGui
private ItemStack createDeleteSubButton() private ItemStack createDeleteSubButton()
{ {
// Orange? Nooo. In the real world this is red. True story. return createSubButton(Material.RED_STAINED_GLASS_PANE, ChatColor.RED + "Delete the map", DELETE_MESSAGES);
return createSubButton(DyeColor.ORANGE, ChatColor.RED + "Delete the map", DELETE_MESSAGES);
} }
private ItemStack createCancelSubButton() private ItemStack createCancelSubButton()
{ {
// YES. Purple = lime. BECAUSE. Just accept it. return createSubButton(Material.LIME_STAINED_GLASS_PANE, ChatColor.GREEN + "Cancel", CANCEL_MESSAGES);
return createSubButton(DyeColor.PURPLE, ChatColor.GREEN + "Cancel", CANCEL_MESSAGES);
} }
private ItemStack createSubButton(DyeColor color, String title, String[] messages) private ItemStack createSubButton(Material color, String title, String[] messages)
{ {
Dye pane = new Dye(Material.STAINED_GLASS_PANE); return new ItemStackBuilder(color)
pane.setColor(color); .title(title)
.loreSeparator()
ItemStack subButton = pane.toItemStack(1); .longLore(ChatColor.GRAY + messages[random.nextInt(messages.length)])
ItemMeta meta = subButton.getItemMeta(); .item();
meta.setDisplayName(title);
meta.setLore(Arrays.asList(
"",
ChatColor.GRAY + messages[random.nextInt(messages.length)]
));
subButton.setItemMeta(meta);
return subButton;
} }
@GuiAction ("cancel") @GuiAction ("cancel")

View File

@ -35,7 +35,7 @@ import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
public class MapDetailGui extends ExplorerGui<Short> public class MapDetailGui extends ExplorerGui<Integer>
{ {
private final ImageMap map; private final ImageMap map;
@ -47,7 +47,7 @@ public class MapDetailGui extends ExplorerGui<Short>
@Override @Override
protected ItemStack getViewItem(int x, int y) protected ItemStack getViewItem(int x, int y)
{ {
final Material partMaterial = y % 2 == x % 2 ? Material.EMPTY_MAP : Material.PAPER; final Material partMaterial = y % 2 == x % 2 ? Material.MAP : Material.PAPER;
final ItemStackBuilder builder = new ItemStackBuilder(partMaterial) final ItemStackBuilder builder = new ItemStackBuilder(partMaterial)
.title(I.t(getPlayerLocale(), "{green}Map part")) .title(I.t(getPlayerLocale(), "{green}Map part"))
@ -61,10 +61,10 @@ public class MapDetailGui extends ExplorerGui<Short>
} }
@Override @Override
protected ItemStack getViewItem(Short mapId) protected ItemStack getViewItem(Integer mapId)
{ {
final int index = ((PosterMap) map).getIndex(mapId); final int index = ((PosterMap) map).getIndex(mapId);
final Material partMaterial = index % 2 == 0 ? Material.EMPTY_MAP : Material.PAPER; final Material partMaterial = index % 2 == 0 ? Material.MAP : Material.PAPER;
final ItemStackBuilder builder = new ItemStackBuilder(partMaterial) final ItemStackBuilder builder = new ItemStackBuilder(partMaterial)
.title(I.t(getPlayerLocale(), "{green}Map part")) .title(I.t(getPlayerLocale(), "{green}Map part"))
@ -95,7 +95,7 @@ public class MapDetailGui extends ExplorerGui<Short>
} }
@Override @Override
protected ItemStack getPickedUpItem(Short mapId) protected ItemStack getPickedUpItem(Integer mapId)
{ {
if (!Permissions.GET.grantedTo(getPlayer())) if (!Permissions.GET.grantedTo(getPlayer()))
return null; return null;
@ -149,7 +149,7 @@ public class MapDetailGui extends ExplorerGui<Short>
if (canRename) if (canRename)
{ {
action("rename", renameSlot, new ItemStackBuilder(Material.BOOK_AND_QUILL) action("rename", renameSlot, new ItemStackBuilder(Material.WRITABLE_BOOK)
.title(I.t(getPlayerLocale(), "{blue}Rename this image")) .title(I.t(getPlayerLocale(), "{blue}Rename this image"))
.longLore(I.t(getPlayerLocale(), "{gray}Click here to rename this image; this is used for your own organization.")) .longLore(I.t(getPlayerLocale(), "{gray}Click here to rename this image; this is used for your own organization."))
); );

View File

@ -29,8 +29,10 @@ import fr.zcraft.zlib.components.gui.ExplorerGui;
import fr.zcraft.zlib.components.gui.Gui; import fr.zcraft.zlib.components.gui.Gui;
import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.components.i18n.I;
import fr.zcraft.zlib.tools.items.ItemStackBuilder; import fr.zcraft.zlib.tools.items.ItemStackBuilder;
import org.bukkit.Color;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
public class MapListGui extends ExplorerGui<ImageMap> public class MapListGui extends ExplorerGui<ImageMap>
@ -58,34 +60,41 @@ public class MapListGui extends ExplorerGui<ImageMap>
mapDescription = I.t(getPlayerLocale(), "{white}Poster map ({0} parts)", poster.getMapCount()); mapDescription = I.t(getPlayerLocale(), "{white}Poster map ({0} parts)", poster.getMapCount());
} }
} }
ItemStackBuilder builder = new ItemStackBuilder(Material.MAP)
ItemStackBuilder builder = new ItemStackBuilder(Material.FILLED_MAP)
/// Displayed title of a map on the list GUI /// Displayed title of a map on the list GUI
.title(I.t(getPlayerLocale(), "{green}{bold}{0}", map.getName())) .title(I.tl(getPlayerLocale(), "{green}{bold}{0}", map.getName()))
.lore(mapDescription) .lore(mapDescription)
.loreLine() .loreLine()
/// Map ID displayed in the tooltip of a map on the list GUI /// Map ID displayed in the tooltip of a map on the list GUI
.lore(I.t(getPlayerLocale(), "{gray}Map ID: {0}", map.getId())) .lore(I.tl(getPlayerLocale(), "{gray}Map ID: {0}", map.getId()))
.loreLine(); .loreLine();
if (Permissions.GET.grantedTo(getPlayer())) if (Permissions.GET.grantedTo(getPlayer()))
builder.lore(I.t(getPlayerLocale(), "{gray}» {white}Left-click{gray} to get this map")); builder.lore(I.tl(getPlayerLocale(), "{gray}» {white}Left-click{gray} to get this map"));
builder.lore(I.t(getPlayerLocale(), "{gray}» {white}Right-click{gray} for details and options")); builder.lore(I.tl(getPlayerLocale(), "{gray}» {white}Right-click{gray} for details and options"));
return builder.item(); final ItemStack mapItem = builder.item();
final MapMeta meta = (MapMeta) mapItem.getItemMeta();
meta.setColor(Color.GREEN);
mapItem.setItemMeta(meta);
return mapItem;
} }
@Override @Override
protected ItemStack getEmptyViewItem() protected ItemStack getEmptyViewItem()
{ {
ItemStackBuilder builder = new ItemStackBuilder(Material.BARRIER) ItemStackBuilder builder = new ItemStackBuilder(Material.BARRIER)
.title(I.t(getPlayerLocale(), "{red}You don't have any map.")); .title(I.tl(getPlayerLocale(), "{red}You don't have any map."));
if (Permissions.NEW.grantedTo(getPlayer())) if (Permissions.NEW.grantedTo(getPlayer()))
builder.longLore(I.t(getPlayerLocale(), "{gray}Get started by creating a new one using {white}/tomap <URL> [resize]{gray}!")); builder.longLore(I.tl(getPlayerLocale(), "{gray}Get started by creating a new one using {white}/tomap <URL> [resize]{gray}!"));
else else
builder.longLore(I.t(getPlayerLocale(), "{gray}Unfortunately, you are not allowed to create one.")); builder.longLore(I.tl(getPlayerLocale(), "{gray}Unfortunately, you are not allowed to create one."));
return builder.item(); return builder.item();
} }
@ -104,7 +113,7 @@ public class MapListGui extends ExplorerGui<ImageMap>
if (map instanceof SingleMap) if (map instanceof SingleMap)
{ {
return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName()); return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName(), false);
} }
else if (map instanceof PosterMap) else if (map instanceof PosterMap)
{ {
@ -128,7 +137,7 @@ public class MapListGui extends ExplorerGui<ImageMap>
setData(maps); setData(maps);
/// The maps list GUI title /// The maps list GUI title
setTitle(I.t(getPlayerLocale(), "{black}Your maps {reset}({0})", maps.length)); setTitle(I.tl(getPlayerLocale(), "{black}Your maps {reset}({0})", maps.length));
setKeepHorizontalScrollingSpace(true); setKeepHorizontalScrollingSpace(true);

View File

@ -60,12 +60,12 @@ public class ImageIOExecutor extends Worker
}); });
} }
static public void saveImage(short mapID, BufferedImage image) static public void saveImage(int mapID, BufferedImage image)
{ {
saveImage(ImageOnMap.getPlugin().getImageFile(mapID), image); saveImage(ImageOnMap.getPlugin().getImageFile(mapID), image);
} }
static public void saveImage(short[] mapsIDs, PosterImage image) static public void saveImage(int[] mapsIDs, PosterImage image)
{ {
for(int i = 0, c = mapsIDs.length; i < c; i++) for(int i = 0, c = mapsIDs.length; i < c; i++)
{ {
@ -75,7 +75,7 @@ public class ImageIOExecutor extends Worker
static public void deleteImage(ImageMap map) static public void deleteImage(ImageMap map)
{ {
short[] mapsIDs = map.getMapsIDs(); int[] mapsIDs = map.getMapsIDs();
for(int i = 0, c = mapsIDs.length; i < c; i++) for(int i = 0, c = mapsIDs.length; i < c; i++)
{ {
deleteImage(ImageOnMap.getPlugin().getImageFile(mapsIDs[i])); deleteImage(ImageOnMap.getPlugin().getImageFile(mapsIDs[i]));

View File

@ -77,16 +77,16 @@ public class ImageRendererExecutor extends Worker
static private ImageMap renderSingle(final BufferedImage image, final UUID playerUUID) throws Throwable static private ImageMap renderSingle(final BufferedImage image, final UUID playerUUID) throws Throwable
{ {
MapManager.checkMapLimit(1, playerUUID); MapManager.checkMapLimit(1, playerUUID);
final Future<Short> futureMapID = submitToMainThread(new Callable<Short>() final Future<Integer> futureMapID = submitToMainThread(new Callable<Integer>()
{ {
@Override @Override
public Short call() throws Exception public Integer call() throws Exception
{ {
return MapManager.getNewMapsIds(1)[0]; return MapManager.getNewMapsIds(1)[0];
} }
}); });
final short mapID = futureMapID.get(); final int mapID = futureMapID.get();
ImageIOExecutor.saveImage(mapID, image); ImageIOExecutor.saveImage(mapID, image);
submitToMainThread(new Callable<Void>() submitToMainThread(new Callable<Void>()
@ -108,10 +108,10 @@ public class ImageRendererExecutor extends Worker
final int mapCount = poster.getImagesCount(); final int mapCount = poster.getImagesCount();
MapManager.checkMapLimit(mapCount, playerUUID); MapManager.checkMapLimit(mapCount, playerUUID);
final Future<short[]> futureMapsIds = submitToMainThread(new Callable<short[]>() final Future<int[]> futureMapsIds = submitToMainThread(new Callable<int[]>()
{ {
@Override @Override
public short[] call() throws Exception public int[] call() throws Exception
{ {
return MapManager.getNewMapsIds(mapCount); return MapManager.getNewMapsIds(mapCount);
} }
@ -119,7 +119,7 @@ public class ImageRendererExecutor extends Worker
poster.splitImages(); poster.splitImages();
final short[] mapsIDs = futureMapsIds.get(); final int[] mapsIDs = futureMapsIds.get();
ImageIOExecutor.saveImage(mapsIDs, poster); ImageIOExecutor.saveImage(mapsIDs, poster);

View File

@ -19,25 +19,26 @@
package fr.moribus.imageonmap.image; package fr.moribus.imageonmap.image;
import fr.moribus.imageonmap.ImageOnMap; import fr.moribus.imageonmap.ImageOnMap;
import fr.moribus.imageonmap.map.MapManager;
import fr.zcraft.zlib.core.ZLib; import fr.zcraft.zlib.core.ZLib;
import java.io.File;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.ItemFrame; import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerItemHeldEvent; import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.map.MapView; import org.bukkit.map.MapView;
import java.io.File;
public class MapInitEvent implements Listener public class MapInitEvent implements Listener
{ {
static public void init() static public void init()
@ -54,7 +55,7 @@ public class MapInitEvent implements Listener
for(Player player : Bukkit.getOnlinePlayers()) for(Player player : Bukkit.getOnlinePlayers())
{ {
initMap(player.getItemInHand()); initMap(player.getInventory().getItemInMainHand());
} }
} }
@ -78,10 +79,10 @@ public class MapInitEvent implements Listener
} }
@EventHandler @EventHandler
public void onPlayerPickup(PlayerPickupItemEvent event) public void onPlayerPickup(EntityPickupItemEvent event)
{ {
ItemStack item = event.getItem().getItemStack(); if (!(event.getEntity() instanceof HumanEntity)) return;
initMap(item); initMap(event.getItem().getItemStack());
} }
@EventHandler @EventHandler
@ -99,15 +100,15 @@ public class MapInitEvent implements Listener
static public void initMap(ItemStack item) static public void initMap(ItemStack item)
{ {
if (item != null && item.getType() == Material.MAP) if (item != null && item.getType() == Material.FILLED_MAP)
{ {
initMap(item.getDurability()); initMap(MapManager.getMapIdFromItemStack(item));
} }
} }
static public void initMap(short id) static public void initMap(int id)
{ {
initMap(Bukkit.getMap(id)); initMap(Bukkit.getServer().getMap(id));
} }
static public void initMap(MapView map) static public void initMap(MapView map)

View File

@ -19,13 +19,14 @@
package fr.moribus.imageonmap.image; package fr.moribus.imageonmap.image;
import fr.zcraft.zlib.tools.PluginLogger; import fr.zcraft.zlib.tools.PluginLogger;
import java.awt.image.BufferedImage;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.map.MapCanvas; import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapRenderer; import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView; import org.bukkit.map.MapView;
import java.awt.image.BufferedImage;
public class Renderer extends MapRenderer public class Renderer extends MapRenderer
{ {
static public boolean isHandled(MapView map) static public boolean isHandled(MapView map)
@ -38,7 +39,7 @@ public class Renderer extends MapRenderer
return false; return false;
} }
static public void installRenderer(PosterImage image, short[] mapsIds) static public void installRenderer(PosterImage image, int[] mapsIds)
{ {
for(int i = 0; i < mapsIds.length; i++) for(int i = 0; i < mapsIds.length; i++)
{ {
@ -46,12 +47,12 @@ public class Renderer extends MapRenderer
} }
} }
static public void installRenderer(BufferedImage image, short mapID) static public void installRenderer(BufferedImage image, int mapID)
{ {
MapView map = Bukkit.getMap(mapID); MapView map = Bukkit.getMap(mapID);
if(map == null) if(map == null)
{ {
PluginLogger.warning("Could not install renderer for map {0} : the Minecraft map does not exist", mapID); PluginLogger.warning("Could not install renderer for map {0}: the Minecraft map does not exist", mapID);
} }
else else
{ {

View File

@ -68,15 +68,15 @@ public abstract class ImageMap implements ConfigurationSerializable
} }
public abstract short[] getMapsIDs(); public abstract int[] getMapsIDs();
public abstract boolean managesMap(short mapID); public abstract boolean managesMap(int mapID);
public abstract int getMapCount(); public abstract int getMapCount();
public boolean managesMap(ItemStack item) public boolean managesMap(ItemStack item)
{ {
if(item == null) return false; if(item == null) return false;
if(item.getType() != Material.MAP) return false; if(item.getType() != Material.FILLED_MAP) return false;
return managesMap(item.getDurability()); return managesMap(MapManager.getMapIdFromItemStack(item));
} }
public boolean give(Player player) public boolean give(Player player)

View File

@ -28,6 +28,8 @@ import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.MapMeta;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import java.io.File; import java.io.File;
@ -53,7 +55,7 @@ abstract public class MapManager
if(autosaveTask != null) autosaveTask.cancel(); if(autosaveTask != null) autosaveTask.cancel();
} }
static public boolean managesMap(short mapID) static public boolean managesMap(int mapID)
{ {
synchronized(playerMaps) synchronized(playerMaps)
{ {
@ -68,7 +70,7 @@ abstract public class MapManager
static public boolean managesMap(ItemStack item) static public boolean managesMap(ItemStack item)
{ {
if(item == null) return false; if(item == null) return false;
if(item.getType() != Material.MAP) return false; if(item.getType() != Material.FILLED_MAP) return false;
synchronized(playerMaps) synchronized(playerMaps)
{ {
@ -80,14 +82,14 @@ abstract public class MapManager
return false; return false;
} }
static public ImageMap createMap(UUID playerUUID, short mapID) throws MapManagerException static public ImageMap createMap(UUID playerUUID, int mapID) throws MapManagerException
{ {
ImageMap newMap = new SingleMap(playerUUID, mapID); ImageMap newMap = new SingleMap(playerUUID, mapID);
addMap(newMap); addMap(newMap);
return newMap; return newMap;
} }
static public ImageMap createMap(PosterImage image, UUID playerUUID, short[] mapsIDs) throws MapManagerException static public ImageMap createMap(PosterImage image, UUID playerUUID, int[] mapsIDs) throws MapManagerException
{ {
ImageMap newMap; ImageMap newMap;
if(image.getImagesCount() == 1) if(image.getImagesCount() == 1)
@ -102,15 +104,28 @@ abstract public class MapManager
return newMap; return newMap;
} }
static public short[] getNewMapsIds(int amount) static public int[] getNewMapsIds(int amount)
{ {
short[] mapsIds = new short[amount]; int[] mapsIds = new int[amount];
for(int i = 0; i < amount; i++) for(int i = 0; i < amount; i++)
{ {
mapsIds[i] = Bukkit.createMap(Bukkit.getWorlds().get(0)).getId(); mapsIds[i] = Bukkit.createMap(Bukkit.getWorlds().get(0)).getId();
} }
return mapsIds; return mapsIds;
} }
/**
* Returns the map ID from an ItemStack
* @param item The item stack
* @return The map ID, or 0 if invalid.
*/
static public int getMapIdFromItemStack(final ItemStack item)
{
final ItemMeta meta = item.getItemMeta();
if (!(meta instanceof MapMeta)) return 0;
return ((MapMeta) meta).hasMapId() ? ((MapMeta) meta).getMapId() : 0;
}
static public void addMap(ImageMap map) throws MapManagerException static public void addMap(ImageMap map) throws MapManagerException
{ {
@ -173,7 +188,7 @@ abstract public class MapManager
* @param mapId The ID of the Minecraft map. * @param mapId The ID of the Minecraft map.
* @return The {@link ImageMap}. * @return The {@link ImageMap}.
*/ */
static public ImageMap getMap(short mapId) static public ImageMap getMap(int mapId)
{ {
synchronized(playerMaps) synchronized(playerMaps)
{ {
@ -204,8 +219,8 @@ abstract public class MapManager
static public ImageMap getMap(ItemStack item) static public ImageMap getMap(ItemStack item)
{ {
if(item == null) return null; if(item == null) return null;
if(item.getType() != Material.MAP) return null; if(item.getType() != Material.FILLED_MAP) return null;
return getMap(item.getDurability()); return getMap(getMapIdFromItemStack(item));
} }
static public void clear(Inventory inventory) static public void clear(Inventory inventory)
@ -312,7 +327,7 @@ abstract public class MapManager
* @param mapId the map ID. * @param mapId the map ID.
* @return true if the given map ID is valid and exists in the current save, false otherwise. * @return true if the given map ID is valid and exists in the current save, false otherwise.
*/ */
static public boolean mapIdExists(short mapId) static public boolean mapIdExists(int mapId)
{ {
try try
{ {

View File

@ -50,7 +50,7 @@ public class PlayerMapStore implements ConfigurationSerializable
this.playerUUID = playerUUID; this.playerUUID = playerUUID;
} }
public synchronized boolean managesMap(short mapID) public synchronized boolean managesMap(int mapID)
{ {
for(ImageMap map : mapList) for(ImageMap map : mapList)
{ {
@ -62,7 +62,7 @@ public class PlayerMapStore implements ConfigurationSerializable
public synchronized boolean managesMap(ItemStack item) public synchronized boolean managesMap(ItemStack item)
{ {
if(item == null) return false; if(item == null) return false;
if(item.getType() != Material.MAP) return false; if(item.getType() != Material.FILLED_MAP) return false;
for(ImageMap map : mapList) for(ImageMap map : mapList)
{ {

View File

@ -26,11 +26,11 @@ import java.util.UUID;
public class PosterMap extends ImageMap public class PosterMap extends ImageMap
{ {
protected final short[] mapsIDs; protected final int[] mapsIDs;
protected final int columnCount; protected final int columnCount;
protected final int rowCount; protected final int rowCount;
public PosterMap(UUID userUUID, short[] mapsIDs, String id, String name, int columnCount, int rowCount) public PosterMap(UUID userUUID, int[] mapsIDs, String id, String name, int columnCount, int rowCount)
{ {
super(userUUID, Type.POSTER, id, name); super(userUUID, Type.POSTER, id, name);
this.mapsIDs = mapsIDs; this.mapsIDs = mapsIDs;
@ -38,19 +38,19 @@ public class PosterMap extends ImageMap
this.rowCount = Math.max(rowCount, 0); this.rowCount = Math.max(rowCount, 0);
} }
public PosterMap(UUID userUUID, short[] mapsIDs, int columnCount, int rowCount) public PosterMap(UUID userUUID, int[] mapsIDs, int columnCount, int rowCount)
{ {
this(userUUID, mapsIDs, null, null, columnCount, rowCount); this(userUUID, mapsIDs, null, null, columnCount, rowCount);
} }
@Override @Override
public short[] getMapsIDs() public int[] getMapsIDs()
{ {
return mapsIDs; return mapsIDs;
} }
@Override @Override
public boolean managesMap(short mapID) public boolean managesMap(int mapID)
{ {
for(int i = 0; i < mapsIDs.length; i++) for(int i = 0; i < mapsIDs.length; i++)
{ {
@ -70,10 +70,10 @@ public class PosterMap extends ImageMap
rowCount = getFieldValue(map, "rows"); rowCount = getFieldValue(map, "rows");
List<Integer> idList = getFieldValue(map, "mapsIDs"); List<Integer> idList = getFieldValue(map, "mapsIDs");
mapsIDs = new short[idList.size()]; mapsIDs = new int[idList.size()];
for(int i = 0, c = idList.size(); i < c; i++) for(int i = 0, c = idList.size(); i < c; i++)
{ {
mapsIDs[i] = (short) ((int) idList.get(i)); mapsIDs[i] = (int) idList.get(i);
} }
} }
@ -131,19 +131,19 @@ public class PosterMap extends ImageMap
* *
* @throws ArrayIndexOutOfBoundsException if the given coordinates are too big (out of the poster). * @throws ArrayIndexOutOfBoundsException if the given coordinates are too big (out of the poster).
*/ */
public short getMapIdAt(int x, int y) public int getMapIdAt(int x, int y)
{ {
return mapsIDs[y * columnCount + x]; return mapsIDs[y * columnCount + x];
} }
public short getMapIdAtReverseY(int index) public int getMapIdAtReverseY(int index)
{ {
int x = index % (columnCount); int x = index % (columnCount);
int y = index / (columnCount); int y = index / (columnCount);
return getMapIdAt(x, rowCount - y - 1); return getMapIdAt(x, rowCount - y - 1);
} }
public short getMapIdAt(int index) public int getMapIdAt(int index)
{ {
return mapsIDs[index]; return mapsIDs[index];
} }
@ -159,7 +159,7 @@ public class PosterMap extends ImageMap
return mapsIDs.length; return mapsIDs.length;
} }
public int getIndex(short mapID) public int getIndex(int mapID)
{ {
for(int i = 0; i < mapsIDs.length; i++) for(int i = 0; i < mapsIDs.length; i++)
{ {

View File

@ -18,33 +18,34 @@
package fr.moribus.imageonmap.map; package fr.moribus.imageonmap.map;
import org.bukkit.configuration.InvalidConfigurationException;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import org.bukkit.configuration.InvalidConfigurationException;
public class SingleMap extends ImageMap public class SingleMap extends ImageMap
{ {
protected final short mapID; protected final int mapID;
public SingleMap(UUID ownerUUID, short mapID, String id, String name) public SingleMap(UUID ownerUUID, int mapID, String id, String name)
{ {
super(ownerUUID, Type.SINGLE, id, name); super(ownerUUID, Type.SINGLE, id, name);
this.mapID = mapID; this.mapID = mapID;
} }
public SingleMap(UUID ownerUUID, short mapID) public SingleMap(UUID ownerUUID, int mapID)
{ {
this(ownerUUID, mapID, null, null); this(ownerUUID, mapID, null, null);
} }
@Override @Override
public short[] getMapsIDs() public int[] getMapsIDs()
{ {
return new short[]{mapID}; return new int[]{mapID};
} }
@Override @Override
public boolean managesMap(short mapID) public boolean managesMap(int mapID)
{ {
return this.mapID == mapID; return this.mapID == mapID;
} }
@ -60,8 +61,7 @@ public class SingleMap extends ImageMap
public SingleMap(Map<String, Object> map, UUID userUUID) throws InvalidConfigurationException public SingleMap(Map<String, Object> map, UUID userUUID) throws InvalidConfigurationException
{ {
super(map, userUUID, Type.SINGLE); super(map, userUUID, Type.SINGLE);
int _mapID = getFieldValue(map, "mapID"); mapID = getFieldValue(map, "mapID");
mapID = (short) _mapID;//Meh
} }
@Override @Override

View File

@ -21,12 +21,14 @@ package fr.moribus.imageonmap.migration;
import fr.moribus.imageonmap.map.ImageMap; import fr.moribus.imageonmap.map.ImageMap;
import fr.moribus.imageonmap.map.MapManager; import fr.moribus.imageonmap.map.MapManager;
import fr.moribus.imageonmap.map.PosterMap; import fr.moribus.imageonmap.map.PosterMap;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.bukkit.configuration.Configuration; import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.InvalidConfigurationException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
class OldSavedPoster class OldSavedPoster
{ {
private final String userName; private final String userName;
@ -78,7 +80,11 @@ class OldSavedPoster
public ImageMap toImageMap(UUID userUUID) public ImageMap toImageMap(UUID userUUID)
{ {
return new PosterMap(userUUID, mapsIds, null, "poster", 0, 0); // Converts the maps IDs to int as MC 1.13.2+ uses integer ids
final int[] mapsIdsInt = new int[mapsIds.length];
Arrays.setAll(mapsIdsInt, i -> mapsIds[i]);
return new PosterMap(userUUID, mapsIdsInt, null, "poster", 0, 0);
} }
public void serialize(Configuration configuration) public void serialize(Configuration configuration)

View File

@ -23,6 +23,8 @@ import fr.moribus.imageonmap.map.MapManager;
import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.components.i18n.I;
import fr.zcraft.zlib.tools.PluginLogger; import fr.zcraft.zlib.tools.PluginLogger;
import fr.zcraft.zlib.tools.mojang.UUIDFetcher; import fr.zcraft.zlib.tools.mojang.UUIDFetcher;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
@ -37,14 +39,8 @@ import java.nio.file.Paths;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayDeque; import java.util.*;
import java.util.ArrayList; import java.util.stream.Collectors;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
/** /**
* This class represents and executes the ImageOnMap v3.x migration process * This class represents and executes the ImageOnMap v3.x migration process
@ -427,7 +423,7 @@ public class V3Migrator implements Runnable
ArrayDeque<OldSavedMap> remainingMaps = new ArrayDeque<>(); ArrayDeque<OldSavedMap> remainingMaps = new ArrayDeque<>();
ArrayDeque<OldSavedPoster> remainingPosters = new ArrayDeque<>(); ArrayDeque<OldSavedPoster> remainingPosters = new ArrayDeque<>();
ArrayDeque<Short> missingMapIds = new ArrayDeque<>(); ArrayDeque<Integer> missingMapIds = new ArrayDeque<>();
UUID playerUUID; UUID playerUUID;
OldSavedMap map; OldSavedMap map;
@ -441,7 +437,7 @@ public class V3Migrator implements Runnable
} }
else if(!map.isMapValid()) else if(!map.isMapValid())
{ {
missingMapIds.add(map.getMapId()); missingMapIds.add((int) map.getMapId());
} }
else else
{ {
@ -461,7 +457,7 @@ public class V3Migrator implements Runnable
} }
else if(!poster.isMapValid()) else if(!poster.isMapValid())
{ {
missingMapIds.addAll(Arrays.asList(ArrayUtils.toObject(poster.getMapsIds()))); missingMapIds.addAll(Arrays.stream(ArrayUtils.toObject(poster.getMapsIds())).map(id -> (int) id).collect(Collectors.toList()));
} }
else else
{ {

View File

@ -22,10 +22,14 @@ import fr.moribus.imageonmap.map.ImageMap;
import fr.moribus.imageonmap.map.MapManager; import fr.moribus.imageonmap.map.MapManager;
import fr.moribus.imageonmap.map.PosterMap; import fr.moribus.imageonmap.map.PosterMap;
import fr.moribus.imageonmap.map.SingleMap; import fr.moribus.imageonmap.map.SingleMap;
import fr.zcraft.zlib.components.attributes.Attributes;
import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.components.i18n.I;
import fr.zcraft.zlib.core.ZLib; import fr.zcraft.zlib.core.ZLib;
import fr.zcraft.zlib.tools.PluginLogger;
import fr.zcraft.zlib.tools.items.ItemStackBuilder; import fr.zcraft.zlib.tools.items.ItemStackBuilder;
import fr.zcraft.zlib.tools.items.ItemUtils; import fr.zcraft.zlib.tools.items.ItemUtils;
import fr.zcraft.zlib.tools.reflection.NMSException;
import org.bukkit.Color;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.ItemFrame; import org.bukkit.entity.ItemFrame;
@ -37,6 +41,7 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.HashMap; import java.util.HashMap;
@ -114,54 +119,77 @@ public class MapItemManager implements Listener
return givenItemsCount; return givenItemsCount;
} }
static private boolean give(Player player, ItemStack item) static private boolean give(final Player player, final ItemStack item)
{ {
if(player.getInventory().firstEmpty() <= -1) final int freeSlot = player.getInventory().firstEmpty();
if (freeSlot != -1)
{ {
getCache(player).add(item); player.getInventory().setItem(freeSlot, item);
return true;
// If this is a splatter map, we have to re-add the splatter attribute, because
// for some reason, the `addItem` or `setItem` methods removes the attribute in
// Minecraft 1.14+, breaking the auto-deploy feature.
if (SplatterMapManager.hasSplatterAttributes(item))
{
try
{
Attributes.set(player.getInventory().getItem(freeSlot), new SplatterMapManager.Attribute());
}
catch (NMSException e)
{
PluginLogger.error("Unable to add back attribute to splatter map");
}
}
return false;
} }
else else
{ {
player.getInventory().addItem(item); ItemUtils.drop(player.getLocation(), item);
return false; return true;
} }
} }
static public ItemStack createMapItem(SingleMap map) static public ItemStack createMapItem(SingleMap map)
{ {
return createMapItem(map.getMapsIDs()[0], map.getName()); return createMapItem(map.getMapsIDs()[0], map.getName(), false);
} }
static public ItemStack createMapItem(PosterMap map, int index) static public ItemStack createMapItem(PosterMap map, int index)
{ {
/// The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = index. return createMapItem(map.getMapIdAt(index), getMapTitle(map, index), true);
return createMapItem(map.getMapIdAt(index), getMapTitle(map, index));
} }
static public ItemStack createMapItem(PosterMap map, int x, int y) static public ItemStack createMapItem(PosterMap map, int x, int y)
{ {
/// The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = row; 2 = column. return createMapItem(map.getMapIdAt(x, y), getMapTitle(map, y, x), true);
return createMapItem(map.getMapIdAt(x, y), getMapTitle(map, y, x));
} }
static public String getMapTitle(PosterMap map, int row, int column) static public String getMapTitle(PosterMap map, int row, int column)
{ {
/// The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = row; 2 = column.
return I.t("{0} (row {1}, column {2})", map.getName(), row + 1, column + 1); return I.t("{0} (row {1}, column {2})", map.getName(), row + 1, column + 1);
} }
static public String getMapTitle(PosterMap map, int index) static public String getMapTitle(PosterMap map, int index)
{ {
/// The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = index.
return I.t("{0} (part {1})", map.getName(), index + 1); return I.t("{0} (part {1})", map.getName(), index + 1);
} }
static public ItemStack createMapItem(short mapID, String text) static public ItemStack createMapItem(int mapID, String text, boolean isMapPart)
{ {
return new ItemStackBuilder(Material.MAP) final ItemStack mapItem = new ItemStackBuilder(Material.FILLED_MAP)
.data(mapID)
.title(text) .title(text)
.hideAttributes() .hideAttributes()
.item(); .item();
final MapMeta meta = (MapMeta) mapItem.getItemMeta();
meta.setMapId(mapID);
meta.setColor(isMapPart ? Color.LIME : Color.GREEN);
mapItem.setItemMeta(meta);
return mapItem;
} }
/** /**
@ -188,7 +216,7 @@ public class MapItemManager implements Listener
throw new ArrayIndexOutOfBoundsException(); // Coherence throw new ArrayIndexOutOfBoundsException(); // Coherence
} }
return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName()); return createMapItem(map.getMapsIDs()[0], map.getName(), false);
} }
} }
@ -218,7 +246,7 @@ public class MapItemManager implements Listener
else else
{ {
PosterMap poster = (PosterMap) map; PosterMap poster = (PosterMap) map;
int index = poster.getIndex(item.getDurability()); int index = poster.getIndex(MapManager.getMapIdFromItemStack(item));
if(poster.hasColumnData()) if(poster.hasColumnData())
return getMapTitle(poster, poster.getRowAt(index), poster.getColumnAt(index)); return getMapTitle(poster, poster.getRowAt(index), poster.getColumnAt(index));
@ -228,19 +256,20 @@ public class MapItemManager implements Listener
static private void onItemFramePlace(ItemFrame frame, Player player, PlayerInteractEntityEvent event) static private void onItemFramePlace(ItemFrame frame, Player player, PlayerInteractEntityEvent event)
{ {
final ItemStack mapItem = player.getInventory().getItemInMainHand();
if(frame.getItem().getType() != Material.AIR) return; if(frame.getItem().getType() != Material.AIR) return;
if(!MapManager.managesMap(player.getItemInHand())) return; if(!MapManager.managesMap(mapItem)) return;
event.setCancelled(true); event.setCancelled(true);
if(SplatterMapManager.hasSplatterAttributes(player.getItemInHand())) if(SplatterMapManager.hasSplatterAttributes(mapItem))
{ {
if(!SplatterMapManager.placeSplatterMap(frame, player)) if(!SplatterMapManager.placeSplatterMap(frame, player))
return; return;
} }
else else
{ {
ItemStack is = new ItemStack(Material.MAP, 1, player.getItemInHand().getDurability()); frame.setItem(player.getInventory().getItemInMainHand());
frame.setItem(is);
} }
ItemUtils.consumeItem(player); ItemUtils.consumeItem(player);
@ -249,7 +278,7 @@ public class MapItemManager implements Listener
static private void onItemFrameRemove(ItemFrame frame, Player player, EntityDamageByEntityEvent event) static private void onItemFrameRemove(ItemFrame frame, Player player, EntityDamageByEntityEvent event)
{ {
ItemStack item = frame.getItem(); ItemStack item = frame.getItem();
if(frame.getItem().getType() != Material.MAP) return; if(frame.getItem().getType() != Material.FILLED_MAP) return;
if(player.isSneaking()) if(player.isSneaking())
{ {
@ -274,22 +303,19 @@ public class MapItemManager implements Listener
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
static public void onEntityDamage(EntityDamageByEntityEvent event) static public void onEntityDamage(EntityDamageByEntityEvent event)
{ {
if(event.isCancelled()) return;
if(!(event.getEntity() instanceof ItemFrame)) return; if(!(event.getEntity() instanceof ItemFrame)) return;
if(!(event.getDamager() instanceof Player)) return; if(!(event.getDamager() instanceof Player)) return;
onItemFrameRemove((ItemFrame)event.getEntity(), (Player)event.getDamager(), event); onItemFrameRemove((ItemFrame)event.getEntity(), (Player)event.getDamager(), event);
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
static public void onEntityInteract(PlayerInteractEntityEvent event) static public void onEntityInteract(PlayerInteractEntityEvent event)
{ {
if(event.isCancelled()) return;
if(!(event.getRightClicked() instanceof ItemFrame)) return; if(!(event.getRightClicked() instanceof ItemFrame)) return;
onItemFramePlace((ItemFrame)event.getRightClicked(), event.getPlayer(), event); onItemFramePlace((ItemFrame)event.getRightClicked(), event.getPlayer(), event);
} }
} }

View File

@ -70,7 +70,7 @@ public class PosterWall
} }
static public ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, short mapId) static public ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, int mapId)
{ {
int mapIndex = map.getIndex(mapId); int mapIndex = map.getIndex(mapId);
int x = map.getColumnAt(mapIndex), y = map.getRowAt(mapIndex); int x = map.getColumnAt(mapIndex), y = map.getRowAt(mapIndex);
@ -111,7 +111,7 @@ public class PosterWall
ItemFrame frame = (ItemFrame) entity; ItemFrame frame = (ItemFrame) entity;
if(frame.getFacing() != location.getFacing()) continue; if(frame.getFacing() != location.getFacing()) continue;
ItemStack item = frame.getItem(); ItemStack item = frame.getItem();
if(item.getType() != Material.MAP) continue; if(item.getType() != Material.FILLED_MAP) continue;
if(!map.managesMap(item)) continue; if(!map.managesMap(item)) continue;
return frame; return frame;
} }

View File

@ -18,21 +18,28 @@
package fr.moribus.imageonmap.ui; package fr.moribus.imageonmap.ui;
import com.google.common.collect.ImmutableMap;
import fr.moribus.imageonmap.image.MapInitEvent; import fr.moribus.imageonmap.image.MapInitEvent;
import fr.moribus.imageonmap.map.ImageMap; import fr.moribus.imageonmap.map.ImageMap;
import fr.moribus.imageonmap.map.MapManager; import fr.moribus.imageonmap.map.MapManager;
import fr.moribus.imageonmap.map.PosterMap; import fr.moribus.imageonmap.map.PosterMap;
import fr.zcraft.zlib.components.gui.GuiUtils; import fr.zcraft.zlib.components.attributes.Attributes;
import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.components.i18n.I;
import fr.zcraft.zlib.tools.items.GlowEffect; import fr.zcraft.zlib.components.nbt.NBTException;
import fr.zcraft.zlib.tools.PluginLogger;
import fr.zcraft.zlib.tools.items.ItemStackBuilder; import fr.zcraft.zlib.tools.items.ItemStackBuilder;
import fr.zcraft.zlib.tools.reflection.NMSException;
import fr.zcraft.zlib.tools.world.FlatLocation; import fr.zcraft.zlib.tools.world.FlatLocation;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.ItemFrame; import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
import java.util.UUID;
abstract public class SplatterMapManager abstract public class SplatterMapManager
{ {
@ -40,8 +47,7 @@ abstract public class SplatterMapManager
static public ItemStack makeSplatterMap(PosterMap map) static public ItemStack makeSplatterMap(PosterMap map)
{ {
return new ItemStackBuilder(Material.MAP) final ItemStack splatter = new ItemStackBuilder(Material.FILLED_MAP)
.data(map.getMapIdAt(0))
.title(ChatColor.GOLD, map.getName()).title(ChatColor.DARK_GRAY, " - ").title(ChatColor.GRAY, I.t("Splatter Map")) .title(ChatColor.GOLD, map.getName()).title(ChatColor.DARK_GRAY, " - ").title(ChatColor.GRAY, I.t("Splatter Map"))
.loreLine(ChatColor.GRAY, map.getId()) .loreLine(ChatColor.GRAY, map.getId())
.loreLine() .loreLine()
@ -52,17 +58,32 @@ abstract public class SplatterMapManager
.loreLine() .loreLine()
/// Title in a splatter map tooltip /// Title in a splatter map tooltip
.loreLine(ChatColor.BLUE, I.t("How to use this?")) .loreLine(ChatColor.BLUE, I.t("How to use this?"))
.lore(GuiUtils.generateLore(ChatColor.GRAY + I.t("Place empty item frames on a wall, enough to host the whole map. Then, right-click on the bottom-left frame with this map."))) .longLore(ChatColor.GRAY + I.t("Place empty item frames on a wall, enough to host the whole map. Then, right-click on the bottom-left frame with this map."))
.loreLine() .loreLine()
.lore(GuiUtils.generateLore(ChatColor.GRAY + I.t("Shift-click one of the placed maps to remove the whole poster in one shot."))) .longLore(ChatColor.GRAY + I.t("Shift-click one of the placed maps to remove the whole poster in one shot."))
.glow()
.hideAttributes() .hideAttributes()
.item(); .craftItem();
final MapMeta meta = (MapMeta) splatter.getItemMeta();
meta.setMapId(map.getMapIdAt(0));
meta.setColor(Color.GREEN);
splatter.setItemMeta(meta);
try
{
Attributes.set(splatter, new Attribute());
}
catch (NBTException | NMSException e)
{
PluginLogger.error("Unable to set Splatter Map attribute on item", e);
}
return splatter;
} }
static public boolean hasSplatterAttributes(ItemStack itemStack) static public boolean hasSplatterAttributes(ItemStack itemStack)
{ {
return GlowEffect.hasGlow(itemStack); return Attribute.hasAttribute(itemStack);
} }
static public boolean isSplatterMap(ItemStack itemStack) static public boolean isSplatterMap(ItemStack itemStack)
@ -86,10 +107,11 @@ abstract public class SplatterMapManager
static public boolean placeSplatterMap(ItemFrame startFrame, Player player) static public boolean placeSplatterMap(ItemFrame startFrame, Player player)
{ {
ImageMap map = MapManager.getMap(player.getItemInHand()); ImageMap map = MapManager.getMap(player.getInventory().getItemInMainHand());
if(map == null || !(map instanceof PosterMap)) return false;
if(!(map instanceof PosterMap)) return false;
PosterMap poster = (PosterMap) map; PosterMap poster = (PosterMap) map;
FlatLocation startLocation = new FlatLocation(startFrame.getLocation(), startFrame.getFacing()); FlatLocation startLocation = new FlatLocation(startFrame.getLocation(), startFrame.getFacing());
FlatLocation endLocation = startLocation.clone().add(poster.getColumnCount(), poster.getRowCount()); FlatLocation endLocation = startLocation.clone().add(poster.getColumnCount(), poster.getRowCount());
PosterWall wall = new PosterWall(); PosterWall wall = new PosterWall();
@ -106,8 +128,8 @@ abstract public class SplatterMapManager
int i = 0; int i = 0;
for(ItemFrame frame : wall.frames) for(ItemFrame frame : wall.frames)
{ {
short id = poster.getMapIdAtReverseY(i); int id = poster.getMapIdAtReverseY(i);
frame.setItem(new ItemStack(Material.MAP, 1, id)); frame.setItem(new ItemStackBuilder(Material.FILLED_MAP).nbt(ImmutableMap.of("map", id)).craftItem());
MapInitEvent.initMap(id); MapInitEvent.initMap(id);
++i; ++i;
} }
@ -117,12 +139,12 @@ abstract public class SplatterMapManager
static public PosterMap removeSplatterMap(ItemFrame startFrame) static public PosterMap removeSplatterMap(ItemFrame startFrame)
{ {
ImageMap map = MapManager.getMap(startFrame.getItem()); final ImageMap map = MapManager.getMap(startFrame.getItem());
if(map == null || !(map instanceof PosterMap)) return null; if(!(map instanceof PosterMap)) return null;
PosterMap poster = (PosterMap) map; PosterMap poster = (PosterMap) map;
if(!poster.hasColumnData()) return null; if(!poster.hasColumnData()) return null;
FlatLocation loc = new FlatLocation(startFrame.getLocation(), startFrame.getFacing()); FlatLocation loc = new FlatLocation(startFrame.getLocation(), startFrame.getFacing());
ItemFrame[] matchingFrames = PosterWall.getMatchingMapFrames(poster, loc, startFrame.getItem().getDurability()); ItemFrame[] matchingFrames = PosterWall.getMatchingMapFrames(poster, loc, MapManager.getMapIdFromItemStack(startFrame.getItem()));
if(matchingFrames == null) return null; if(matchingFrames == null) return null;
for(ItemFrame frame : matchingFrames) for(ItemFrame frame : matchingFrames)
@ -132,4 +154,29 @@ abstract public class SplatterMapManager
return poster; return poster;
} }
static public class Attribute extends fr.zcraft.zlib.components.attributes.Attribute
{
static public final UUID SPLATTER_MAP_UUID = UUID.fromString("260ae1b3-4b24-40a0-a30d-67ad84b7bdb2");
Attribute()
{
setUUID(SPLATTER_MAP_UUID);
setCustomData("splatter-map");
}
static boolean hasAttribute(final ItemStack item)
{
try
{
return Attributes.get(item, SPLATTER_MAP_UUID) != null;
}
catch (NMSException | NBTException ex)
{
PluginLogger.warning("Error while retrieving SplatterMap Attribute data", ex);
return false;
}
}
}
} }

View File

@ -1,6 +1,7 @@
name: ImageOnMap name: ImageOnMap
main: fr.moribus.imageonmap.ImageOnMap main: fr.moribus.imageonmap.ImageOnMap
version: 3.1 version: "4.0"
api-version: "1.13"
commands: commands:
tomap: tomap: