/******************************************************************************* * This file is part of ASkyBlock. * * ASkyBlock 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. * * ASkyBlock 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 ASkyBlock. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************/ package com.wasteofplastic.askyblock.panels; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryType.SlotType; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.SkullMeta; import com.wasteofplastic.askyblock.ASkyBlock; import com.wasteofplastic.askyblock.Island; import com.wasteofplastic.askyblock.Island.SettingsFlag; import com.wasteofplastic.askyblock.Settings; import com.wasteofplastic.askyblock.util.Util; public class WarpPanel implements Listener { private ASkyBlock plugin; private List<Inventory> warpPanel; private static final int PANELSIZE = 45; // Must be a multiple of 9 // The list of all players who have warps and their corresponding inventory icon // A stack of zero amount will mean they are not active private HashMap<UUID, ItemStack> cachedWarps; private final static boolean DEBUG = false; /** * @param plugin */ public WarpPanel(ASkyBlock plugin) { this.plugin = plugin; warpPanel = new ArrayList<Inventory>(); cachedWarps = new HashMap<UUID,ItemStack>(); //plugin.getLogger().info("DEBUG: loading the warp panel of size " + plugin.getWarpSignsListener().listSortedWarps().size()); // Load the cache for (UUID playerUUID : plugin.getWarpSignsListener().listSortedWarps()) { addWarp(playerUUID); } // Make the panels updatePanel(); } /** * Only change the text of the warp * @param playerUUID */ public void updateWarp(UUID playerUUID) { if (DEBUG) plugin.getLogger().info("DEBUG: update Warp"); if (cachedWarps.containsKey(playerUUID)) { // Get the item ItemStack playerSkull = cachedWarps.get(playerUUID); playerSkull = updateText(playerSkull, playerUUID); updatePanel(); } else { plugin.getLogger().warning("Warps: update requested, but player unknown " + playerUUID.toString()); } } /** * Update the text on all the warp icons. */ public void updateAllWarpText() { if (DEBUG) plugin.getLogger().info("DEBUG: update all Warps"); for (UUID playerUUID : cachedWarps.keySet()) { // Get the item ItemStack playerSkull = cachedWarps.get(playerUUID); playerSkull = updateText(playerSkull, playerUUID); } updatePanel(); } /** * Adds a new warp to the cache. Does NOT update the panels * @param playerUUID */ public void addWarp(UUID playerUUID) { if (DEBUG) plugin.getLogger().info("DEBUG: Adding warp"); // Check cached warps if (cachedWarps.containsKey(playerUUID)) { if (DEBUG) plugin.getLogger().info("DEBUG: Found in cache"); // Get the item ItemStack playerSkull = cachedWarps.get(playerUUID); playerSkull = updateText(playerSkull, playerUUID); return; } //plugin.getLogger().info("DEBUG: New skull"); // Get the item ItemStack playerSkull = getSkull(playerUUID); if (playerSkull == null) { // Nothing found and not available on the server return; } // Update the sign text playerSkull = updateText(playerSkull, playerUUID); cachedWarps.put(playerUUID, playerSkull); } /** * Gets the skull for this player UUID * @param playerUUID * @return Player skull item */ private ItemStack getSkull(UUID playerUUID) { String playerName = plugin.getServer().getOfflinePlayer(playerUUID).getName(); if (DEBUG) plugin.getLogger().info("DEBUG: name of warp = " + playerName); ItemStack playerSkull = new ItemStack(Material.SKULL_ITEM, 1, (short) 3); if (playerName == null) { if (DEBUG) plugin.getLogger().warning("Warp for Player: UUID " + playerUUID.toString() + " is unknown on this server, skipping..."); return null; //playerName = playerUUID.toString().substring(0, 10); } SkullMeta meta = (SkullMeta) playerSkull.getItemMeta(); meta.setOwner(playerName); meta.setDisplayName(ChatColor.WHITE + playerName); playerSkull.setItemMeta(meta); return playerSkull; } /** * Updates the meta text on the skull by looking at the warp sign * This MUST be run 1 TICK AFTER the sign has been created otherwise the sign is blank * @param playerSkull * @param playerUUID * @return updated skull item stack */ private ItemStack updateText(ItemStack playerSkull, final UUID playerUUID) { if (DEBUG) plugin.getLogger().info("DEBUG: Updating text on item"); ItemMeta meta = playerSkull.getItemMeta(); //get the sign info Location signLocation = plugin.getWarpSignsListener().getWarp(playerUUID); //plugin.getLogger().info("DEBUG: block type = " + signLocation.getBlock().getType()); // Get the sign info if it exists if (signLocation.getBlock().getType().equals(Material.SIGN_POST) || signLocation.getBlock().getType().equals(Material.WALL_SIGN)) { Sign sign = (Sign)signLocation.getBlock().getState(); List<String> lines = new ArrayList<String>(Arrays.asList(sign.getLines())); // Check for PVP and add warning Island island = plugin.getGrid().getIsland(playerUUID); if (island != null) { if ((signLocation.getWorld().equals(ASkyBlock.getIslandWorld()) && island.getIgsFlag(SettingsFlag.PVP)) || (signLocation.getWorld().equals(ASkyBlock.getNetherWorld()) && island.getIgsFlag(SettingsFlag.NETHER_PVP))) { if (DEBUG) plugin.getLogger().info("DEBUG: pvp warning added"); lines.add(ChatColor.RED + plugin.myLocale().igs.get(SettingsFlag.PVP)); } } meta.setLore(lines); if (DEBUG) plugin.getLogger().info("DEBUG: lines = " + lines); } playerSkull.setItemMeta(meta); return playerSkull; } /** * Creates the inventory panels from the warp list and adds nav buttons */ public void updatePanel() { // Clear the inventory panels warpPanel.clear(); Collection<UUID> activeWarps = plugin.getWarpSignsListener().listSortedWarps(); // Create the warp panels if (DEBUG) plugin.getLogger().info("DEBUG: warps size = " + activeWarps.size()); int size = activeWarps.size(); int panelNumber = size / (PANELSIZE-2); int remainder = (size % (PANELSIZE-2)) + 8 + 2; remainder -= (remainder % 9); if (DEBUG) plugin.getLogger().info("DEBUG: panel number = " + panelNumber + " remainder = " + remainder); int i = 0; // TODO: Make panel title a string for (i = 0; i < panelNumber; i++) { if (DEBUG) plugin.getLogger().info("DEBUG: created panel " + (i+1)); warpPanel.add(Bukkit.createInventory(null, PANELSIZE, plugin.myLocale().warpsTitle + " #" + (i+1))); } // Make the last panel if (DEBUG) plugin.getLogger().info("DEBUG: created panel " + (i+1)); warpPanel.add(Bukkit.createInventory(null, remainder, plugin.myLocale().warpsTitle + " #" + (i+1))); panelNumber = 0; int slot = 0; // Run through all the warps and add them to the inventories with nav buttons for (UUID playerUUID: activeWarps) { ItemStack icon = cachedWarps.get(playerUUID); if (icon != null) { warpPanel.get(panelNumber).setItem(slot++, icon); // Check if the panel is full if (slot == PANELSIZE-2) { // Add navigation buttons if (panelNumber > 0) { warpPanel.get(panelNumber).setItem(slot++, new CPItem(Material.SIGN,plugin.myLocale().warpsPrevious,"warps " + (panelNumber-1),"").getItem()); } warpPanel.get(panelNumber).setItem(slot, new CPItem(Material.SIGN,plugin.myLocale().warpsNext,"warps " + (panelNumber+1),"").getItem()); // Move onto the next panel panelNumber++; slot = 0; } } } if (remainder != 0 && panelNumber > 0) { warpPanel.get(panelNumber).setItem(slot++, new CPItem(Material.SIGN,plugin.myLocale().warpsPrevious,"warps " + (panelNumber-1),"").getItem()); } } public Inventory getWarpPanel(int panelNumber) { //makePanel(); if (panelNumber < 0) { panelNumber = 0; } else if (panelNumber > warpPanel.size()-1) { panelNumber = warpPanel.size()-1; } return warpPanel.get(panelNumber); } @SuppressWarnings("deprecation") @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled=true) public void onInventoryClick(InventoryClickEvent event) { Inventory inventory = event.getInventory(); // The inventory that was clicked in if (inventory.getName() == null) { return; } String title = inventory.getTitle(); if (!inventory.getTitle().startsWith(plugin.myLocale().warpsTitle + " #")) { return; } // The player that clicked the item Player player = (Player) event.getWhoClicked(); event.setCancelled(true); if (event.getSlotType().equals(SlotType.OUTSIDE)) { player.closeInventory(); return; } if (event.getClick().equals(ClickType.SHIFT_RIGHT)) { player.closeInventory(); player.updateInventory(); return; } ItemStack clicked = event.getCurrentItem(); // The item that was clicked if (DEBUG) plugin.getLogger().info("DEBUG: inventory size = " + inventory.getSize()); if (DEBUG) plugin.getLogger().info("DEBUG: clicked = " + clicked); if (DEBUG) plugin.getLogger().info("DEBUG: rawslot = " + event.getRawSlot()); if (event.getRawSlot() >= event.getInventory().getSize() || clicked.getType() == Material.AIR) { return; } int panelNumber = 0; try { panelNumber = Integer.valueOf(title.substring(title.indexOf('#')+ 1)); } catch (Exception e) { panelNumber = 0; } if (clicked.getItemMeta().hasDisplayName()) { String command = ChatColor.stripColor(clicked.getItemMeta().getDisplayName()); if (DEBUG) plugin.getLogger().info("DEBUG: command = " + command); if (command != null) { if (command.equalsIgnoreCase(ChatColor.stripColor(plugin.myLocale().warpsNext))) { player.closeInventory(); player.performCommand(Settings.ISLANDCOMMAND + " warps " + (panelNumber+1)); } else if (command.equalsIgnoreCase(ChatColor.stripColor(plugin.myLocale().warpsPrevious))) { player.closeInventory(); player.performCommand(Settings.ISLANDCOMMAND + " warps " + (panelNumber-1)); } else { player.closeInventory(); Util.sendMessage(player, ChatColor.GREEN + plugin.myLocale(player.getUniqueId()).warpswarpToPlayersSign.replace("<player>", command)); player.performCommand(Settings.ISLANDCOMMAND + " warp " + command); } } } } }