diff --git a/src/main/java/fr/moribus/imageonmap/commands/Commands.java b/src/main/java/fr/moribus/imageonmap/commands/Commands.java index c237c6c..b03cb4e 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/Commands.java +++ b/src/main/java/fr/moribus/imageonmap/commands/Commands.java @@ -18,22 +18,15 @@ package fr.moribus.imageonmap.commands; -import fr.moribus.imageonmap.commands.maptool.MigrateCommand; -import fr.moribus.imageonmap.PluginLogger; +import fr.moribus.imageonmap.*; import fr.moribus.imageonmap.commands.maptool.*; -import java.io.InputStream; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Scanner; +import org.apache.commons.lang.*; +import org.bukkit.command.*; +import org.bukkit.plugin.java.*; -import org.apache.commons.lang.StringUtils; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.bukkit.plugin.java.JavaPlugin; +import java.io.*; +import java.lang.reflect.*; +import java.util.*; public enum Commands implements TabCompleter, CommandExecutor @@ -45,6 +38,7 @@ public enum Commands implements TabCompleter, CommandExecutor DeleteConfirmCommand.class, DeleteNoConfirmCommand.class, GetRemainingCommand.class, + ManageCommand.class, MigrateCommand.class ), TOMAP(MAPTOOL, NewCommand.class, "tomap"); diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/ManageCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/ManageCommand.java new file mode 100644 index 0000000..3e7b5ff --- /dev/null +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/ManageCommand.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013 Moribus + * Copyright (C) 2015 ProkopyL + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package fr.moribus.imageonmap.commands.maptool; + + +import fr.moribus.imageonmap.commands.*; +import fr.moribus.imageonmap.gui.core.*; +import fr.moribus.imageonmap.gui.list.*; + + +@CommandInfo(name = "manage") +public class ManageCommand extends Command +{ + + public ManageCommand(Commands commandGroup) { + super(commandGroup); + } + + @Override + protected void run() throws CommandException { + GuiManager.openGui(playerSender(), new CategorySelectionGui()); + } +} diff --git a/src/main/java/fr/moribus/imageonmap/gui/list/CategorySelectionGui.java b/src/main/java/fr/moribus/imageonmap/gui/list/CategorySelectionGui.java new file mode 100644 index 0000000..8123f3f --- /dev/null +++ b/src/main/java/fr/moribus/imageonmap/gui/list/CategorySelectionGui.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2013 Moribus + * Copyright (C) 2015 ProkopyL + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package fr.moribus.imageonmap.gui.list; + +import fr.moribus.imageonmap.gui.core.*; +import fr.moribus.imageonmap.map.*; +import org.bukkit.*; +import org.bukkit.entity.*; +import org.bukkit.inventory.*; +import org.bukkit.inventory.meta.*; + + +public class CategorySelectionGui extends AbstractGui { + + @Override + public void display(Player player) + { + + inventory = Bukkit.createInventory(player, 3 * 9, ChatColor.BLACK + "Maps » Choose a category"); + + + ItemStack singleMaps = new ItemStack(Material.MAP); + ItemMeta meta = singleMaps.getItemMeta(); + meta.setDisplayName(ChatColor.GREEN + "Single maps"); + singleMaps.setItemMeta(meta); + + + ItemStack postersMaps = new ItemStack(Material.PAINTING); + meta = postersMaps.getItemMeta(); + meta.setDisplayName(ChatColor.GREEN + "Posters"); + postersMaps.setItemMeta(meta); + + + setSlotData(singleMaps, 11, "single"); + setSlotData(postersMaps, 15, "poster"); + + player.openInventory(getInventory()); + } + + @Override + public void onClick(Player player, ItemStack stack, String action) + { + + switch (action) + { + case "poster": + GuiManager.openGui(player, new MapListGui(ImageMap.Type.POSTER)); + break; + + case "single": + GuiManager.openGui(player, new MapListGui(ImageMap.Type.SINGLE)); + break; + } + } +} diff --git a/src/main/java/fr/moribus/imageonmap/gui/list/MapListGui.java b/src/main/java/fr/moribus/imageonmap/gui/list/MapListGui.java new file mode 100644 index 0000000..04705df --- /dev/null +++ b/src/main/java/fr/moribus/imageonmap/gui/list/MapListGui.java @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2013 Moribus + * Copyright (C) 2015 ProkopyL + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package fr.moribus.imageonmap.gui.list; + +import fr.moribus.imageonmap.gui.core.*; +import fr.moribus.imageonmap.map.*; +import org.bukkit.*; +import org.bukkit.entity.*; +import org.bukkit.event.inventory.*; +import org.bukkit.inventory.*; +import org.bukkit.inventory.meta.*; + +import java.util.*; + + +public class MapListGui extends AbstractGui { + + private final Integer MAPS_PER_PAGE = 7 * 3; + + + private ImageMap.Type mapsType; + + private List maps = new ArrayList<>(); + + private int currentPage = 0; + private int lastPage = 0; + + + public MapListGui(ImageMap.Type mapsType) { + this.mapsType = mapsType; + } + + @Override + public void display(Player player) { + + String inventoryTitle = "Maps » "; + if(mapsType == ImageMap.Type.POSTER) { + inventoryTitle += "Posters"; + } else { + inventoryTitle += "Single maps"; + } + + inventory = Bukkit.createInventory(player, 6 * 9, ChatColor.BLACK + inventoryTitle); + + ItemStack back = new ItemStack(Material.EMERALD); + ItemMeta meta = back.getItemMeta(); + meta.setDisplayName(ChatColor.GREEN + "« Back"); + meta.setLore(Arrays.asList( + ChatColor.GRAY + "Go back to the map", + ChatColor.GRAY + "type selector." + )); + back.setItemMeta(meta); + + setSlotData(back, inventory.getSize() - 5, "back"); + + player.openInventory(getInventory()); + + update(player); + } + + @Override + public void update(Player player) { + update(player, false); + } + + public void update(final Player player, final Boolean noCache) { + if (maps == null || maps.isEmpty() || noCache) { + updateMapCache(player); + } + + + if(maps.isEmpty()) { + ItemStack empty = new ItemStack(Material.BARRIER); + ItemMeta meta = empty.getItemMeta(); + meta.setDisplayName(ChatColor.RED + "Nothing to display here"); + meta.setLore(Arrays.asList( + ChatColor.GRAY + "You don't have any map in", + ChatColor.GRAY + "this category. Try the other", + ChatColor.GRAY + "one, or create a new map with", + ChatColor.WHITE + "/tomap [resize]" + )); + + empty.setItemMeta(meta); + + setSlotData(empty, 13, ""); + + return; + } + + + int index = currentPage * MAPS_PER_PAGE; + int lastIndex = index + MAPS_PER_PAGE; + int slot = 10; + + ImageMap map; + + for (; index < lastIndex; index++) { + try { + map = maps.get(index); + setSlotData(getMapIcon(map), slot, map.getId()); + } catch(IndexOutOfBoundsException e) { + setSlotData(new ItemStack(Material.AIR), slot, ""); + } + + if (slot % 9 == 7) slot += 3; + else slot++; + } + + if (currentPage != 0) + setSlotData(getPageIcon(currentPage - 1), inventory.getSize() - 9, "previousPage"); + else + setSlotData(new ItemStack(Material.AIR), inventory.getSize() - 9, ""); + + if (currentPage != lastPage) + setSlotData(getPageIcon(currentPage + 1), inventory.getSize() - 1, "nextPage"); + else + setSlotData(new ItemStack(Material.AIR), inventory.getSize() - 1, ""); + } + + @Override + public void onClick(Player player, ItemStack stack, String action, ClickType clickType) { + + switch (action) + { + case "back": + GuiManager.openGui(player, new CategorySelectionGui()); + return; + + case "previousPage": + previousPage(player); + return; + + case "nextPage": + nextPage(player); + return; + + default: + // The action is the map ID + ImageMap map = null; + for(ImageMap lookupMap : maps) + { + if(lookupMap.getId().equals(action)) + { + map = lookupMap; + break; + } + } + + if(map == null) return; + + switch (clickType) + { + case LEFT: + case SHIFT_LEFT: + if(map.give(player)) + { + player.sendMessage(ChatColor.GRAY + "The requested map was too big to fit in your inventory."); + player.sendMessage(ChatColor.GRAY + "Use '/maptool getremaining' to get the remaining maps."); + } + + player.closeInventory(); + + break; + + case RIGHT: + case SHIFT_RIGHT: + // TODO + break; + } + + } + + } + + private void nextPage(Player player) + { + if(currentPage < lastPage) currentPage++; + + update(player); + } + + private void previousPage(Player player) + { + if(currentPage > 0) currentPage--; + + update(player); + } + + + private void updateMapCache(Player player) + { + for(ImageMap map : MapManager.getMapList(player.getUniqueId())) + { + if(map.getType() == mapsType) maps.add(map); + } + + lastPage = (int) Math.ceil(((double) maps.size()) / ((double) MAPS_PER_PAGE)) - 1; + + if(currentPage > lastPage) + currentPage = lastPage; + } + + private ItemStack getMapIcon(ImageMap map) + { + ItemStack icon = new ItemStack(Material.MAP); + + + ItemMeta meta = icon.getItemMeta(); + + meta.setDisplayName(ChatColor.GREEN + "" + ChatColor.BOLD + map.getId().replace("-", " ")); + + if(map.getType() == ImageMap.Type.POSTER) + { + meta.setLore(Arrays.asList( + ChatColor.WHITE + "" + map.getMapCount() + " map" + (map.getMapCount() != 1 ? "s" : "") + )); + } + + else + { + meta.setLore(Arrays.asList( + ChatColor.WHITE + "Single map" + )); + } + + List lore = meta.getLore(); + lore.addAll(Arrays.asList( + "", + ChatColor.GRAY + "» Left-click to get this map", + ChatColor.GRAY + "» Right-click for details" + )); + meta.setLore(lore); + + icon.setItemMeta(meta); + + + return icon; + } + + private ItemStack getPageIcon(Integer targetPage) + { + ItemStack icon = new ItemStack(Material.ARROW); + ItemMeta meta = icon.getItemMeta(); + + + if(currentPage < targetPage) { // next page + meta.setDisplayName(ChatColor.GREEN + "Next page"); + } + else { + meta.setDisplayName(ChatColor.GREEN + "Previous page"); + } + + meta.setLore(Collections.singletonList( + ChatColor.GRAY + "Go to page " + ChatColor.WHITE + (targetPage + 1) + ChatColor.GRAY + " of " + ChatColor.WHITE + (lastPage + 1) + )); + + + icon.setItemMeta(meta); + + return icon; + } +} diff --git a/src/main/java/fr/moribus/imageonmap/map/ImageMap.java b/src/main/java/fr/moribus/imageonmap/map/ImageMap.java index 390a4a8..ef46e64 100644 --- a/src/main/java/fr/moribus/imageonmap/map/ImageMap.java +++ b/src/main/java/fr/moribus/imageonmap/map/ImageMap.java @@ -18,15 +18,14 @@ package fr.moribus.imageonmap.map; -import fr.moribus.imageonmap.ui.MapItemManager; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import org.bukkit.Material; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.serialization.ConfigurationSerializable; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; +import fr.moribus.imageonmap.ui.*; +import org.bukkit.*; +import org.bukkit.configuration.*; +import org.bukkit.configuration.serialization.*; +import org.bukkit.entity.*; +import org.bukkit.inventory.*; + +import java.util.*; public abstract class ImageMap implements ConfigurationSerializable { @@ -160,6 +159,11 @@ public abstract class ImageMap implements ConfigurationSerializable return id; } + public synchronized Type getType() + { + return mapType; + } + public synchronized void rename(String id, String name) { this.id = id;