diff --git a/src/com/gmail/St3venAU/plugins/ArmorStandTools/ArmorStandGUI.java b/src/com/gmail/St3venAU/plugins/ArmorStandTools/ArmorStandGUI.java new file mode 100644 index 0000000..947e0ad --- /dev/null +++ b/src/com/gmail/St3venAU/plugins/ArmorStandTools/ArmorStandGUI.java @@ -0,0 +1,255 @@ +package com.gmail.St3venAU.plugins.ArmorStandTools; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryDragEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.HashSet; +import java.util.UUID; + +class ArmorStandGUI implements Listener { + + private static final HashSet inUse = new HashSet(); + private static final HashSet invSlots = new HashSet(); + private static ItemStack filler; + + private Inventory i; + private ArmorStand as; + private Main plugin; + + ArmorStandGUI(Main plugin, ArmorStand as, Player p) { + if(inUse.contains(as.getEntityId())) { + p.sendMessage(ChatColor.RED + "This armor stand's GUI is in use"); + return; + } + if(filler == null) { + filler = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 15); + ItemMeta im = filler.getItemMeta(); + im.setDisplayName(" "); + filler.setItemMeta(im); + invSlots.add(0); + invSlots.add(9); + invSlots.add(10); + invSlots.add(18); + invSlots.add(27); + } + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + this.as = as; + String name = as.getCustomName(); + if(name == null) { + name = "Armor Stand"; + } + i = Bukkit.createInventory(null, 36, name); + for(int slot = 0; slot < i.getSize(); slot++) { + i.setItem(slot, filler); + } + for(ArmorStandTool tool : ArmorStandTool.values()) { + if(tool.isForGui() && tool.isEnabled()) { + i.setItem(tool.getSlot(), updateLore(tool)); + } + } + i.setItem(0, as.getHelmet()); + i.setItem(9, as.getChestplate()); + i.setItem(10, as.getItemInHand()); + i.setItem(18, as.getLeggings()); + i.setItem(27, as.getBoots()); + inUse.add(as.getEntityId()); + p.openInventory(i); + } + + ItemStack updateLore(ArmorStandTool tool) { + ItemStack item = tool.getItem(); + switch (tool) { + case INVIS: + return Utils.setLore(item, ChatColor.AQUA + Config.asVisible + ": " + (as.isVisible() ? (ChatColor.GREEN + Config.isTrue) : (ChatColor.RED + Config.isFalse))); + case SIZE: + return Utils.setLore(item, ChatColor.AQUA + Config.size + ": " + (as.isSmall() ? (ChatColor.BLUE + Config.small) : (ChatColor.GREEN + Config.normal))); + case BASE: + return Utils.setLore(item, ChatColor.AQUA + Config.basePlate + ": " + (as.hasBasePlate() ? (ChatColor.GREEN + Config.isOn) : (ChatColor.RED + Config.isOff))); + case GRAV: + return Utils.setLore(item, ChatColor.AQUA + Config.gravity + ": " + (as.hasGravity() ? (ChatColor.GREEN + Config.isOn) : (ChatColor.RED + Config.isOff))); + case ARMS: + return Utils.setLore(item, ChatColor.AQUA + Config.arms + ": " + (as.hasArms() ? (ChatColor.GREEN + Config.isOn) : (ChatColor.RED + Config.isOff))); + case INVUL: + return Utils.setLore(item, ChatColor.AQUA + Config.invul + ": " + (NBT.isInvulnerable(as) ? (ChatColor.GREEN + Config.isOn) : (ChatColor.RED + Config.isOff))); + case SLOTS: + return Utils.setLore(item, ChatColor.AQUA + Config.equip + ": " + (NBT.getDisabledSlots(as) == 2039583 ? (ChatColor.GREEN + Config.locked) : (ChatColor.RED + Config.unLocked))); + case NODEL: + return Utils.setLore(item, ChatColor.AQUA + "Deletion Protection: " + (as.getMaxHealth() == 50 ? (ChatColor.GREEN + "Enabled") : (ChatColor.RED + "Disabled"))); + case NAME: + return Utils.setLore(item, ChatColor.AQUA + Config.currently + ": " + (as.getCustomName() == null ? (ChatColor.BLUE + "None") : (ChatColor.GREEN + as.getCustomName()))); + case PHEAD: + String name = plrHeadName(as); + return Utils.setLore(item, ChatColor.AQUA + Config.currently + ": " + (name == null ? (ChatColor.BLUE + "None") : (ChatColor.GREEN + name))); + default: + return item; + } + } + + String plrHeadName(ArmorStand as) { + if(as.getHelmet() == null) return null; + if(!(as.getHelmet().getItemMeta() instanceof SkullMeta)) return null; + SkullMeta meta = (SkullMeta) as.getHelmet().getItemMeta(); + if(!meta.hasOwner()) return null; + return meta.getOwner(); + } + + @EventHandler + public void inInventoryClose(InventoryCloseEvent event) { + if(!event.getInventory().equals(i)) return; + HandlerList.unregisterAll(this); + inUse.remove(as.getEntityId()); + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) { + if(!event.getInventory().equals(i)) return; + Player p = (Player) event.getWhoClicked(); + if(event.getClick() == ClickType.SHIFT_LEFT || event.getClick() == ClickType.SHIFT_RIGHT || event.getClick() == ClickType.NUMBER_KEY) { + event.setCancelled(true); + return; + } + int slot = event.getRawSlot(); + if(slot > i.getSize()) return; + if(invSlots.contains(slot)) { + if(plugin.checkPermission(p, as.getLocation().getBlock())) { + updateInventory(); + } else { + event.setCancelled(true); + p.sendMessage(ChatColor.RED + Config.wgNoPerm); + } + return; + } + event.setCancelled(true); + if(!(event.getWhoClicked() instanceof Player)) return; + ArmorStandTool t = ArmorStandTool.get(event.getCurrentItem()); + if(t == null) return; + if (!plugin.playerHasPermission(p, as.getLocation().getBlock(), t)) { + p.sendMessage(ChatColor.RED + Config.generalNoPerm); + return; + } + switch (t) { + case INVIS: + as.setVisible(!as.isVisible()); + Utils.actionBarMsg(p, ChatColor.GREEN + Config.asVisible + ": " + (as.isVisible() ? Config.isTrue : Config.isFalse)); + break; + case CLONE: + p.closeInventory(); + plugin.pickUpArmorStand(plugin.clone(as), p, true); + Utils.actionBarMsg(p, ChatColor.GREEN + Config.carrying); + break; + case SAVE: + plugin.generateCmdBlock(p.getLocation(), as); + Utils.actionBarMsg(p, ChatColor.GREEN + Config.cbCreated); + break; + case SIZE: + as.setSmall(!as.isSmall()); + Utils.actionBarMsg(p, ChatColor.GREEN + Config.size + ": " + (as.isSmall() ? Config.small : Config.normal)); + break; + case BASE: + as.setBasePlate(!as.hasBasePlate()); + Utils.actionBarMsg(p, ChatColor.GREEN + Config.basePlate + ": " + (as.hasBasePlate() ? Config.isOn : Config.isOff)); + break; + case GRAV: + as.setGravity(!as.hasGravity()); + Utils.actionBarMsg(p, ChatColor.GREEN + Config.gravity + ": " + (as.hasGravity() ? Config.isOn : Config.isOff)); + break; + case ARMS: + as.setArms(!as.hasArms()); + Utils.actionBarMsg(p, ChatColor.GREEN + Config.arms + ": " + (as.hasArms() ? Config.isOn : Config.isOff)); + break; + case NAME: + p.closeInventory(); + plugin.setName(p, as); + break; + case PHEAD: + p.closeInventory(); + plugin.setPlayerSkull(p, as); + break; + case INVUL: + Utils.actionBarMsg(p, ChatColor.GREEN + Config.invul + ": " + (NBT.toggleInvulnerability(as) ? Config.isOn : Config.isOff)); + break; + case SLOTS: + Utils.actionBarMsg(p, ChatColor.GREEN + Config.equip + ": " + (NBT.toggleSlotsDisabled(as) ? Config.locked : Config.unLocked)); + break; + case MOVE: + p.closeInventory(); + UUID uuid = p.getUniqueId(); + if(plugin.carryingArmorStand.containsKey(uuid)) { + plugin.carryingArmorStand.remove(uuid); + Utils.actionBarMsg(p, Config.asDropped); + } else { + plugin.pickUpArmorStand(as, p, false); + Utils.actionBarMsg(p, ChatColor.GREEN + Config.carrying); + } + break; + case NODEL: // Developer tool - do not use + if(as.getMaxHealth() == 50) { + as.setMaxHealth(20); + Utils.actionBarMsg(p, ChatColor.GREEN + "Deletion Protection: Disabled"); + } else { + as.setMaxHealth(50); + Utils.actionBarMsg(p, ChatColor.GREEN + "Deletion Protection: Enabled"); + } + break; + default: + return; + } + i.setItem(t.getSlot(), updateLore(t)); + } + + @EventHandler + public void onInventoryDrag(InventoryDragEvent event) { + if(!event.getInventory().equals(i) || !(event.getWhoClicked() instanceof Player)) return; + Player p = (Player) event.getWhoClicked(); + boolean invModified = false; + for(int slot : event.getRawSlots()) { + if(slot < i.getSize()) { + if(invSlots.contains(slot)) { + invModified = true; + } else { + event.setCancelled(true); + return; + } + } + } + if(invModified) { + if(plugin.checkPermission(p, as.getLocation().getBlock())) { + updateInventory(); + } else { + event.setCancelled(true); + p.sendMessage(ChatColor.RED + Config.wgNoPerm); + } + } + } + + void updateInventory() { + new BukkitRunnable() { + @Override + public void run() { + if(as == null || i == null) return; + as.setHelmet(i.getItem(0)); + as.setChestplate(i.getItem(9)); + as.setItemInHand(i.getItem(10)); + as.setLeggings(i.getItem(18)); + as.setBoots(i.getItem(27)); + } + }.runTaskLater(plugin, 1L); + } + +} \ No newline at end of file diff --git a/src/com/gmail/St3venAU/plugins/ArmorStandTools/ArmorStandTool.java b/src/com/gmail/St3venAU/plugins/ArmorStandTools/ArmorStandTool.java index 8ae055c..29f38b5 100644 --- a/src/com/gmail/St3venAU/plugins/ArmorStandTools/ArmorStandTool.java +++ b/src/com/gmail/St3venAU/plugins/ArmorStandTools/ArmorStandTool.java @@ -9,52 +9,55 @@ import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.meta.ItemMeta; public enum ArmorStandTool { - HEADX ("headX", Material.JACK_O_LANTERN, (short) 0, 27, true), - HEADY ("headY", Material.JACK_O_LANTERN, (short) 0, 28, true), - HEADZ ("headZ", Material.JACK_O_LANTERN, (short) 0, 29, true), - LARMX ("lArmX", Material.TORCH, (short) 0, 30, true), - LARMY ("lArmY", Material.TORCH, (short) 0, 31, true), - LARMZ ("lArmZ", Material.TORCH, (short) 0, 32, true), - RARMX ("rArmX", Material.REDSTONE_TORCH_ON, (short) 0, 33, true), - RARMY ("rArmY", Material.REDSTONE_TORCH_ON, (short) 0, 34, true), - RARMZ ("rArmZ", Material.REDSTONE_TORCH_ON, (short) 0, 35, true), - MOVEX ("moveX", Material.SHEARS, (short) 0, 24, true), - MOVEY ("moveY", Material.SHEARS, (short) 0, 25, true), - MOVEZ ("moveZ", Material.SHEARS, (short) 0, 26, true), - ROTAT ("rotat", Material.MAGMA_CREAM, (short) 0, 6, true), - INVIS ("invis", Material.GOLD_NUGGET, (short) 0, 5, true), - SUMMON ("summon", Material.ARMOR_STAND, (short) 0, 0, true), - CLONE ("clone", Material.GLOWSTONE_DUST, (short) 0, 16, true), - SAVE ("save", Material.DIAMOND, (short) 0, 17, true), - LLEGX ("lLegX", Material.BONE, (short) 0, 18, true), - LLEGY ("lLegY", Material.BONE, (short) 0, 19, true), - LLEGZ ("lLegZ", Material.BONE, (short) 0, 20, true), - RLEGX ("rLegX", Material.BLAZE_ROD, (short) 0, 21, true), - RLEGY ("rLegY", Material.BLAZE_ROD, (short) 0, 22, true), - RLEGZ ("rLegZ", Material.BLAZE_ROD, (short) 0, 23, true), - BODYX ("bodyX", Material.NETHER_BRICK_ITEM, (short) 0, 9, true), - BODYY ("bodyY", Material.NETHER_BRICK_ITEM, (short) 0, 10, true), - BODYZ ("bodyZ", Material.NETHER_BRICK_ITEM, (short) 0, 11, true), - SIZE ("size", Material.EMERALD, (short) 0, 3, true), - BASE ("base", Material.BOOK, (short) 0, 4, true), - GRAV ("grav", Material.GHAST_TEAR, (short) 0, 1, true), - ARMS ("arms", Material.ARROW, (short) 0, 2, true), - NAME ("name", Material.NAME_TAG, (short) 0, 7, true), - SLOTS ("slots", Material.IRON_HOE, (short) 0, 13, true), - PHEAD ("pHead", Material.SKULL_ITEM, (short) 3, 8, true), - INVUL ("invul", Material.GOLDEN_CARROT, (short) 0, 12, true), - MOVE ("move", Material.FEATHER, (short) 0, 14, true), - NODEL ("noDel", Material.WOOD_SPADE, (short) 0, 15, false); // Developer tool, disabled by default + HEADX ("headX", Material.JACK_O_LANTERN, (short) 0, 12, false, true), + HEADY ("headY", Material.JACK_O_LANTERN, (short) 0, 13, false, true), + HEADZ ("headZ", Material.JACK_O_LANTERN, (short) 0, 14, false, true), + LARMX ("lArmX", Material.TORCH, (short) 0, 27, false, true), + LARMY ("lArmY", Material.TORCH, (short) 0, 28, false, true), + LARMZ ("lArmZ", Material.TORCH, (short) 0, 29, false, true), + RARMX ("rArmX", Material.REDSTONE_TORCH_ON, (short) 0, 30, false, true), + RARMY ("rArmY", Material.REDSTONE_TORCH_ON, (short) 0, 31, false, true), + RARMZ ("rArmZ", Material.REDSTONE_TORCH_ON, (short) 0, 32, false, true), + MOVEX ("moveX", Material.SHEARS, (short) 0, 3, false, true), + MOVEY ("moveY", Material.SHEARS, (short) 0, 4, false, true), + MOVEZ ("moveZ", Material.SHEARS, (short) 0, 5, false, true), + LLEGX ("lLegX", Material.BONE, (short) 0, 18, false, true), + LLEGY ("lLegY", Material.BONE, (short) 0, 19, false, true), + LLEGZ ("lLegZ", Material.BONE, (short) 0, 20, false, true), + RLEGX ("rLegX", Material.BLAZE_ROD, (short) 0, 21, false, true), + RLEGY ("rLegY", Material.BLAZE_ROD, (short) 0, 22, false, true), + RLEGZ ("rLegZ", Material.BLAZE_ROD, (short) 0, 23, false, true), + BODYX ("bodyX", Material.NETHER_BRICK_ITEM, (short) 0, 9, false, true), + BODYY ("bodyY", Material.NETHER_BRICK_ITEM, (short) 0, 10, false, true), + BODYZ ("bodyZ", Material.NETHER_BRICK_ITEM, (short) 0, 11, false, true), + SUMMON ("summon", Material.ARMOR_STAND, (short) 0, 0, false, true), + GUI ("gui", Material.NETHER_STAR, (short) 0, 1, false, true), + ROTAT ("rotat", Material.MAGMA_CREAM, (short) 0, 2, false, true), + CLONE ("gui_clone", Material.GLOWSTONE_DUST, (short) 0, 16, true, true), + SAVE ("gui_save", Material.DIAMOND, (short) 0, 17, true, true), + INVIS ("gui_invis", Material.GOLD_NUGGET, (short) 0, 14, true, true), + SIZE ("gui_size", Material.EMERALD, (short) 0, 23, true, true), + BASE ("gui_base", Material.BOOK, (short) 0, 22, true, true), + GRAV ("gui_grav", Material.GHAST_TEAR, (short) 0, 24, true, true), + ARMS ("gui_arms", Material.ARROW, (short) 0, 21, true, true), + NAME ("gui_name", Material.NAME_TAG, (short) 0, 12, true, true), + SLOTS ("gui_slots", Material.IRON_HOE, (short) 0, 26, true, true), + PHEAD ("gui_pHead", Material.SKULL_ITEM, (short) 3, 13, true, true), + INVUL ("gui_invul", Material.GOLDEN_CARROT, (short) 0, 25, true, true), + MOVE ("gui_move", Material.FEATHER, (short) 0, 15, true, true), + NODEL ("gui_noDel", Material.WOOD_SPADE, (short) 0, 35, true, false); // Developer tool, disabled by default private final ItemStack item; private final String id; private final int slot; private final boolean enabled; - - ArmorStandTool(String id, Material m, short data, int slot, boolean enabled) { + private final boolean forGui; + + ArmorStandTool(String id, Material m, short data, int slot, boolean forGui, boolean enabled) { item = new ItemStack(m, 1, data); this.id = id; this.slot = slot; + this.forGui = forGui; this.enabled = enabled; } @@ -64,14 +67,26 @@ public enum ArmorStandTool { boolean is(ItemStack is) { return is != null && is.getType() == item.getType() && is.hasItemMeta() && - is.getItemMeta().hasDisplayName() && - is.getItemMeta().getDisplayName().equals(item.getItemMeta().getDisplayName()); + is.getItemMeta().hasDisplayName() && + is.getItemMeta().getDisplayName().equals(item.getItemMeta().getDisplayName()); + } + + boolean isForGui() { + return forGui; + } + + boolean isEnabled() { + return enabled; + } + + int getSlot() { + return slot; } static void updateTools(FileConfiguration config) { for(ArmorStandTool t : values()) { ItemMeta im = t.item.getItemMeta(); - im.setDisplayName(ChatColor.GREEN + config.getString("tool." + t.id + ".name")); + im.setDisplayName(ChatColor.YELLOW + config.getString("tool." + t.id + ".name")); im.setLore(config.getStringList("tool." + t.id + ".lore")); t.item.setItemMeta(im); } @@ -80,7 +95,7 @@ public enum ArmorStandTool { static void give(Player p) { PlayerInventory i = p.getInventory(); for(ArmorStandTool t : values()) { - if(t.enabled) { + if(t.enabled && !t.forGui) { i.setItem(t.slot, t.item); } } @@ -97,4 +112,4 @@ public enum ArmorStandTool { static boolean isTool(ItemStack is) { return get(is) != null; } -} +} \ No newline at end of file diff --git a/src/com/gmail/St3venAU/plugins/ArmorStandTools/Commands.java b/src/com/gmail/St3venAU/plugins/ArmorStandTools/Commands.java index cbfccee..b832989 100644 --- a/src/com/gmail/St3venAU/plugins/ArmorStandTools/Commands.java +++ b/src/com/gmail/St3venAU/plugins/ArmorStandTools/Commands.java @@ -25,6 +25,7 @@ class Commands implements CommandExecutor { Player p = (Player) sender; if (!Utils.hasPermissionNode(p, "astools.command")) { p.sendMessage(ChatColor.RED + Config.noCommandPerm); + return true; } if(args.length == 0) { UUID uuid = p.getUniqueId(); diff --git a/src/com/gmail/St3venAU/plugins/ArmorStandTools/Config.java b/src/com/gmail/St3venAU/plugins/ArmorStandTools/Config.java index 0dd6d8e..7cef41e 100644 --- a/src/com/gmail/St3venAU/plugins/ArmorStandTools/Config.java +++ b/src/com/gmail/St3venAU/plugins/ArmorStandTools/Config.java @@ -31,12 +31,13 @@ class Config { public static String invReturned, asDropped, asVisible, isTrue, isFalse, - asCloned, carrying, noPerm, cbCreated, size, small, + carrying, cbCreated, size, small, normal, basePlate, isOn, isOff, gravity, arms, invul, equip, locked, unLocked, notConsole, giveMsg1, giveMsg2, conReload, noRelPerm, noAirError, pleaseWait, appliedHead, noHead, invalidName, - wgNoPerm, noCommandPerm; + wgNoPerm, currently, headFailed, noCommandPerm, + generalNoPerm; public static void reload(Main main) { plugin = main; @@ -53,9 +54,7 @@ class Config { asVisible = languageConfig.getString("asVisible"); isTrue = languageConfig.getString("isTrue"); isFalse = languageConfig.getString("isFalse"); - asCloned = languageConfig.getString("asCloned"); carrying = languageConfig.getString("carrying"); - noPerm = languageConfig.getString("noPerm"); cbCreated = languageConfig.getString("cbCreated"); size = languageConfig.getString("size"); small = languageConfig.getString("small"); @@ -81,6 +80,9 @@ class Config { invalidName = languageConfig.getString("invalidName"); wgNoPerm = languageConfig.getString("wgNoPerm"); noCommandPerm = languageConfig.getString("noCommandPerm"); + currently = languageConfig.getString("currently"); + headFailed = languageConfig.getString("headFailed"); + generalNoPerm = languageConfig.getString("generalNoPerm"); } private static void reloadMainConfig() { diff --git a/src/com/gmail/St3venAU/plugins/ArmorStandTools/Main.java b/src/com/gmail/St3venAU/plugins/ArmorStandTools/Main.java index 083206f..9d34fca 100644 --- a/src/com/gmail/St3venAU/plugins/ArmorStandTools/Main.java +++ b/src/com/gmail/St3venAU/plugins/ArmorStandTools/Main.java @@ -1,13 +1,22 @@ package com.gmail.St3venAU.plugins.ArmorStandTools; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.CommandBlock; import org.bukkit.command.CommandExecutor; import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.MetadataValue; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.EulerAngle; import java.util.HashMap; import java.util.UUID; @@ -16,6 +25,7 @@ public class Main extends JavaPlugin { public final HashMap carryingArmorStand = new HashMap(); public final HashMap savedInventories = new HashMap(); + private final EulerAngle zero = new EulerAngle(0D, 0D, 0D); static String NMS_VERSION; @Override @@ -56,4 +66,156 @@ public class Main extends JavaPlugin { } as.remove(); } + + void pickUpArmorStand(ArmorStand as, Player p, boolean newlySummoned) { + carryingArmorStand.put(p.getUniqueId(), as); + if(newlySummoned) return; + as.setMetadata("startLoc", new FixedMetadataValue(this, as.getLocation())); + } + + @SuppressWarnings({"deprecation", "ConstantConditions"}) + void generateCmdBlock(Location l, ArmorStand as) { + Location loc = as.getLocation(); + int dSlots = NBT.getDisabledSlots(as); + int hand = as.getItemInHand() == null ? 0 : as.getItemInHand().getTypeId(); + int handDmg = as.getItemInHand() == null ? 0 : as.getItemInHand().getDurability(); + int boots = as.getBoots() == null ? 0 : as.getBoots().getTypeId(); + int bootsDmg = as.getBoots() == null ? 0 : as.getBoots().getDurability(); + int legs = as.getLeggings() == null ? 0 : as.getLeggings().getTypeId(); + int legsDmg = as.getLeggings() == null ? 0 : as.getLeggings().getDurability(); + int chest = as.getChestplate() == null ? 0 : as.getChestplate().getTypeId(); + int chestDmg = as.getChestplate() == null ? 0 : as.getChestplate().getDurability(); + int helm = as.getHelmet() == null ? 0 : as.getHelmet().getTypeId(); + int helmDmg = as.getHelmet() == null ? 0 : as.getHelmet().getDurability(); + EulerAngle he = as.getHeadPose(); + EulerAngle ll = as.getLeftLegPose(); + EulerAngle rl = as.getRightLegPose(); + EulerAngle la = as.getLeftArmPose(); + EulerAngle ra = as.getRightArmPose(); + EulerAngle bo = as.getBodyPose(); + String cmd = + "summon ArmorStand " + Utils.twoDec(loc.getX()) + " " + Utils.twoDec(loc.getY()) + " " + Utils.twoDec(loc.getZ()) + " {" + + (as.getMaxHealth() != 20 ? "Attributes:[{Name:\"generic.maxHealth\", Base:" + as.getMaxHealth() + "}]," : "") + + (as.isVisible() ? "" : "Invisible:1,") + + (as.hasBasePlate() ? "" : "NoBasePlate:1,") + + (as.hasGravity() ? "" : "NoGravity:1,") + + (as.hasArms() ? "ShowArms:1," : "") + + (as.isSmall() ? "Small:1," : "") + + (NBT.isInvulnerable(as) ? "Invulnerable:1," : "") + + (dSlots == 0 ? "" : ("DisabledSlots:" + dSlots + ",")) + + (as.isCustomNameVisible() ? "CustomNameVisible:1," : "") + + (as.getCustomName() == null ? "" : ("CustomName:\"" + as.getCustomName() + "\",")) + + (loc.getYaw() == 0F ? "" : ("Rotation:[" + Utils.twoDec(loc.getYaw()) + "f],")) + + (hand == 0 && boots == 0 && legs == 0 && chest == 0 && helm == 0 ? "" : ( + "Equipment:[" + + "{id:" + hand + ",Count:" + as.getItemInHand().getAmount() + ",Damage:" + handDmg + NBT.getItemStackTags(as.getItemInHand()) + "}," + + "{id:" + boots + ",Count:" + as.getBoots().getAmount() + ",Damage:" + bootsDmg + NBT.getItemStackTags(as.getBoots()) + "}," + + "{id:" + legs + ",Count:" + as.getLeggings().getAmount() + ",Damage:" + legsDmg + NBT.getItemStackTags(as.getLeggings()) + "}," + + "{id:" + chest + ",Count:" + as.getChestplate().getAmount() + ",Damage:" + chestDmg + NBT.getItemStackTags(as.getChestplate()) + "}," + + "{id:" + helm + ",Count:" + as.getHelmet().getAmount() + ",Damage:" + helmDmg + NBT.getItemStackTags(as.getHelmet()) + NBT.skullOwner(as.getHelmet()) + "}],")) + + "Pose:{" + + (bo.equals(zero) ? "" : ("Body:[" + Utils.angle(bo.getX()) + "f," + Utils.angle(bo.getY()) + "f," + Utils.angle(bo.getZ()) + "f],")) + + (he.equals(zero) ? "" : ("Head:[" + Utils.angle(he.getX()) + "f," + Utils.angle(he.getY()) + "f," + Utils.angle(he.getZ()) + "f],")) + + (ll.equals(zero) ? "" : ("LeftLeg:[" + Utils.angle(ll.getX()) + "f," + Utils.angle(ll.getY()) + "f," + Utils.angle(ll.getZ()) + "f],")) + + (rl.equals(zero) ? "" : ("RightLeg:[" + Utils.angle(rl.getX()) + "f," + Utils.angle(rl.getY()) + "f," + Utils.angle(rl.getZ()) + "f],")) + + (la.equals(zero) ? "" : ("LeftArm:[" + Utils.angle(la.getX()) + "f," + Utils.angle(la.getY()) + "f," + Utils.angle(la.getZ()) + "f],")) + + "RightArm:[" + Utils.angle(ra.getX()) + "f," + Utils.angle(ra.getY()) + "f," + Utils.angle(ra.getZ()) + "f]}}"; + Block b = l.getBlock(); + b.setType(Material.COMMAND); + b.setData((byte) 0); + CommandBlock cb = (CommandBlock) b.getState(); + cb.setCommand(cmd); + cb.update(); + } + + ArmorStand clone(ArmorStand as) { + ArmorStand clone = (ArmorStand) as.getWorld().spawnEntity(as.getLocation().add(1, 0, 0), EntityType.ARMOR_STAND); + clone.setGravity(as.hasGravity()); + clone.setHelmet(as.getHelmet()); + clone.setChestplate(as.getChestplate()); + clone.setLeggings(as.getLeggings()); + clone.setBoots(as.getBoots()); + clone.setItemInHand(as.getItemInHand()); + clone.setHeadPose(as.getHeadPose()); + clone.setBodyPose(as.getBodyPose()); + clone.setLeftArmPose(as.getLeftArmPose()); + clone.setRightArmPose(as.getRightArmPose()); + clone.setLeftLegPose(as.getLeftLegPose()); + clone.setRightLegPose(as.getRightLegPose()); + clone.setVisible(as.isVisible()); + clone.setBasePlate(as.hasBasePlate()); + clone.setArms(as.hasArms()); + clone.setCustomName(as.getCustomName()); + clone.setCustomNameVisible(as.isCustomNameVisible()); + clone.setSmall(as.isSmall()); + clone.setMaxHealth(as.getMaxHealth()); + NBT.setSlotsDisabled(clone, NBT.getDisabledSlots(as) == 2039583); + NBT.setInvulnerable(clone, NBT.isInvulnerable(as)); + return clone; + } + + @SuppressWarnings("deprecation") + void setName(Player p, ArmorStand as) { + Block b = Utils.findAnAirBlock(p.getLocation()); + if(b == null) { + p.sendMessage(ChatColor.RED + Config.noAirError); + return; + } + b.setData((byte) 0); + b.setType(Material.SIGN_POST); + Utils.openSign(p, b); + b.setMetadata("armorStand", new FixedMetadataValue(this, as.getUniqueId())); + b.setMetadata("setName", new FixedMetadataValue(this, true)); + } + + @SuppressWarnings("deprecation") + void setPlayerSkull(Player p, ArmorStand as) { + Block b = Utils.findAnAirBlock(p.getLocation()); + if(b == null) { + p.sendMessage(ChatColor.RED + Config.noAirError); + return; + } + b.setData((byte) 0); + b.setType(Material.SIGN_POST); + Utils.openSign(p, b); + b.setMetadata("armorStand", new FixedMetadataValue(this, as.getUniqueId())); + b.setMetadata("setSkull", new FixedMetadataValue(this, true)); + } + + boolean checkPermission(Player player, Block block) { + + if(block == null) return true; + + // Check PlotSquared + Location loc = block.getLocation(); + if (PlotSquaredHook.api != null) { + if (PlotSquaredHook.isPlotWorld(loc)) { + return PlotSquaredHook.checkPermission(player, loc); + } + } + + // check WorldGuard + if(Config.worldGuardPlugin != null) { + return Config.worldGuardPlugin.canBuild(player, block); + } + + // Use standard permission checking (will support basically any plugin) + BlockBreakEvent myBreak = new BlockBreakEvent(block, player); + Bukkit.getServer().getPluginManager().callEvent(myBreak); + boolean hasPerm = !myBreak.isCancelled(); + BlockPlaceEvent place = new BlockPlaceEvent(block, block.getState(), block, null, player, true); + Bukkit.getServer().getPluginManager().callEvent(place); + if (place.isCancelled()) { + hasPerm = false; + } + return hasPerm; + } + + boolean playerHasPermission(Player p, Block b, ArmorStandTool tool) { + return !(tool != null && !p.isOp() + && (!Utils.hasPermissionNode(p, "astools.use") + || (ArmorStandTool.SAVE == tool && !Utils.hasPermissionNode(p, "astools.cmdblock")) + || (ArmorStandTool.CLONE == tool && !Utils.hasPermissionNode(p, "astools.clone")))) + && checkPermission(p, b); + } } \ No newline at end of file diff --git a/src/com/gmail/St3venAU/plugins/ArmorStandTools/MainListener.java b/src/com/gmail/St3venAU/plugins/ArmorStandTools/MainListener.java index 8d91aeb..8d72e94 100644 --- a/src/com/gmail/St3venAU/plugins/ArmorStandTools/MainListener.java +++ b/src/com/gmail/St3venAU/plugins/ArmorStandTools/MainListener.java @@ -1,14 +1,13 @@ package com.gmail.St3venAU.plugins.ArmorStandTools; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.SkullType; import org.bukkit.block.Block; -import org.bukkit.block.CommandBlock; import org.bukkit.block.Skull; import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Player; @@ -30,10 +29,10 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.MetadataValue; import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.EulerAngle; import java.util.Arrays; import java.util.List; @@ -43,7 +42,6 @@ import java.util.regex.Pattern; public class MainListener implements Listener { private final Pattern MC_USERNAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_]{3,16}$"); - private final EulerAngle zero = new EulerAngle(0D, 0D, 0D); private final Main plugin; MainListener(Main main) { @@ -56,7 +54,7 @@ public class MainListener implements Listener { if (event.getRightClicked() instanceof ArmorStand) { Player p = event.getPlayer(); if(plugin.carryingArmorStand.containsKey(p.getUniqueId())) { - if (playerHasPermission(p, plugin.carryingArmorStand.get(p.getUniqueId()).getLocation().getBlock(), null)) { + if (plugin.playerHasPermission(p, plugin.carryingArmorStand.get(p.getUniqueId()).getLocation().getBlock(), null)) { plugin.carryingArmorStand.remove(p.getUniqueId()); Utils.actionBarMsg(p, Config.asDropped); event.setCancelled(true); @@ -68,8 +66,9 @@ public class MainListener implements Listener { ArmorStandTool tool = ArmorStandTool.get(p.getItemInHand()); if(tool == null) return; ArmorStand as = (ArmorStand) event.getRightClicked(); - if (!playerHasPermission(p, event.getRightClicked().getLocation().getBlock(), tool)) { - p.sendMessage(ChatColor.RED + Config.wgNoPerm); + if (!plugin.playerHasPermission(p, event.getRightClicked().getLocation().getBlock(), tool)) { + p.sendMessage(ChatColor.RED + Config.generalNoPerm); + event.setCancelled(true); return; } double num = event.getClickedPosition().getY() - 0.05; @@ -151,65 +150,8 @@ public class MainListener implements Listener { l.setYaw(((float) num) * 180F); as.teleport(l); break; - case INVIS: - as.setVisible(!as.isVisible()); - p.sendMessage(ChatColor.GREEN + Config.asVisible + ": " + (as.isVisible() ? Config.isTrue : Config.isFalse)); - break; - case CLONE: - pickUpArmorStand(clone(as), p, true); - p.sendMessage(ChatColor.GREEN + Config.asCloned); - Utils.actionBarMsg(p, ChatColor.GREEN + Config.carrying); - break; - case SAVE: - generateCmdBlock(p.getLocation(), as); - p.sendMessage(ChatColor.GREEN + Config.cbCreated); - break; - case SIZE: - as.setSmall(!as.isSmall()); - p.sendMessage(ChatColor.GREEN + Config.size + ": " + (as.isSmall() ? Config.small : Config.normal)); - break; - case BASE: - as.setBasePlate(!as.hasBasePlate()); - p.sendMessage(ChatColor.GREEN + Config.basePlate + ": " + (as.hasBasePlate() ? Config.isOn : Config.isOff)); - break; - case GRAV: - as.setGravity(!as.hasGravity()); - p.sendMessage(ChatColor.GREEN + Config.gravity + ": " + (as.hasGravity() ? Config.isOn : Config.isOff)); - break; - case ARMS: - as.setArms(!as.hasArms()); - p.sendMessage(ChatColor.GREEN + Config.arms + ": " + (as.hasArms() ? Config.isOn : Config.isOff)); - break; - case NAME: - setName(p, as); - break; - case PHEAD: - setPlayerSkull(p, as); - break; - case INVUL: - p.sendMessage(ChatColor.GREEN + Config.invul + ": " + (NBT.toggleInvulnerability(as) ? Config.isOn : Config.isOff)); - break; - case SLOTS: - p.sendMessage(ChatColor.GREEN + Config.equip + ": " + (NBT.toggleSlotsDisabled(as) ? Config.locked : Config.unLocked)); - break; - case MOVE: - UUID uuid = p.getUniqueId(); - if(plugin.carryingArmorStand.containsKey(uuid)) { - plugin.carryingArmorStand.remove(uuid); - Utils.actionBarMsg(p, Config.asDropped); - } else { - pickUpArmorStand(as, p, false); - Utils.actionBarMsg(p, ChatColor.GREEN + Config.carrying); - } - break; - case NODEL: // Developer tool - do not use - if(as.getMaxHealth() == 50) { - as.setMaxHealth(20); - p.sendMessage(ChatColor.GREEN + "Deletion Protection: Disabled"); - } else { - as.setMaxHealth(50); - p.sendMessage(ChatColor.GREEN + "Deletion Protection: Enabled"); - } + case GUI: + new ArmorStandGUI(plugin, as, p); break; default: cancel = tool == ArmorStandTool.SUMMON || tool == ArmorStandTool.SAVE || event.isCancelled(); @@ -224,37 +166,9 @@ public class MainListener implements Listener { if (event.getRightClicked() instanceof ItemFrame && ArmorStandTool.isTool(event.getPlayer().getItemInHand())) { event.setCancelled(true); event.getPlayer().updateInventory(); - } else if(!(event.getRightClicked() instanceof ArmorStand) && ArmorStandTool.NAME.is(event.getPlayer().getItemInHand())) { - event.setCancelled(true); } } - private ArmorStand clone(ArmorStand as) { - ArmorStand clone = (ArmorStand) as.getWorld().spawnEntity(as.getLocation().add(1, 0, 0), EntityType.ARMOR_STAND); - clone.setGravity(as.hasGravity()); - clone.setHelmet(as.getHelmet()); - clone.setChestplate(as.getChestplate()); - clone.setLeggings(as.getLeggings()); - clone.setBoots(as.getBoots()); - clone.setItemInHand(as.getItemInHand()); - clone.setHeadPose(as.getHeadPose()); - clone.setBodyPose(as.getBodyPose()); - clone.setLeftArmPose(as.getLeftArmPose()); - clone.setRightArmPose(as.getRightArmPose()); - clone.setLeftLegPose(as.getLeftLegPose()); - clone.setRightLegPose(as.getRightLegPose()); - clone.setVisible(as.isVisible()); - clone.setBasePlate(as.hasBasePlate()); - clone.setArms(as.hasArms()); - clone.setCustomName(as.getCustomName()); - clone.setCustomNameVisible(as.isCustomNameVisible()); - clone.setSmall(as.isSmall()); - clone.setMaxHealth(as.getMaxHealth()); - NBT.setSlotsDisabled(clone, NBT.getDisabledSlots(as) == 2039583); - NBT.setInvulnerable(clone, NBT.isInvulnerable(as)); - return clone; - } - @EventHandler public void onBlockPlace(BlockPlaceEvent event) { if (ArmorStandTool.isTool(event.getItemInHand())) { @@ -347,39 +261,31 @@ public class MainListener implements Listener { public void onPlayerInteract(PlayerInteractEvent event) { Player p = event.getPlayer(); if(plugin.carryingArmorStand.containsKey(p.getUniqueId())) { - boolean perm = playerHasPermission(p, plugin.carryingArmorStand.get(p.getUniqueId()).getLocation().getBlock(), null); - if (perm) { + if (plugin.playerHasPermission(p, plugin.carryingArmorStand.get(p.getUniqueId()).getLocation().getBlock(), null)) { plugin.carryingArmorStand.remove(p.getUniqueId()); Utils.actionBarMsg(p, Config.asDropped); + p.setMetadata("lastDrop", new FixedMetadataValue(plugin, System.currentTimeMillis())); event.setCancelled(true); } else { p.sendMessage(ChatColor.RED + Config.wgNoPerm); } return; } - Action action = event.getAction(); ArmorStandTool tool = ArmorStandTool.get(event.getItem()); if(tool == null) return; + event.setCancelled(true); + Action action = event.getAction(); if(action == Action.LEFT_CLICK_AIR || action == Action.LEFT_CLICK_BLOCK) { - event.setCancelled(true); Utils.cycleInventory(p); - } else if(action == Action.RIGHT_CLICK_BLOCK) { - if (!playerHasPermission(p, event.getClickedBlock(), tool)) { - p.sendMessage(ChatColor.RED + Config.wgNoPerm); + } else if((action == Action.RIGHT_CLICK_BLOCK || action == Action.RIGHT_CLICK_AIR) && tool == ArmorStandTool.SUMMON) { + if (!plugin.playerHasPermission(p, event.getClickedBlock(), tool)) { + p.sendMessage(ChatColor.RED + Config.generalNoPerm); return; } - switch (tool) { - case SUMMON: - event.setCancelled(true); - Location l = Utils.getLocationFacingPlayer(p); - pickUpArmorStand(spawnArmorStand(l), p, true); - Utils.actionBarMsg(p, ChatColor.GREEN + Config.carrying); - p.updateInventory(); - break; - case NAME: - event.setCancelled(true); - break; - } + Location l = Utils.getLocationFacingPlayer(p); + plugin.pickUpArmorStand(spawnArmorStand(l), p, true); + Utils.actionBarMsg(p, ChatColor.GREEN + Config.carrying); + p.updateInventory(); } } @@ -387,10 +293,21 @@ public class MainListener implements Listener { public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { if(event.getEntity() instanceof ArmorStand && event.getDamager() instanceof Player && ArmorStandTool.isTool(((Player) event.getDamager()).getItemInHand())) { event.setCancelled(true); - Utils.cycleInventory((Player) event.getDamager()); + if(noCooldown(event.getDamager())) { + Utils.cycleInventory((Player) event.getDamager()); + } } } + private boolean noCooldown(Entity e) { + for(MetadataValue meta : e.getMetadata("lastDrop")) { + if(meta.getOwningPlugin() == plugin) { + return System.currentTimeMillis() - meta.asFloat() > 100; + } + } + return true; + } + private ArmorStand spawnArmorStand(Location l) { ArmorStand as = (ArmorStand) l.getWorld().spawnEntity(l, EntityType.ARMOR_STAND); as.setHelmet(Config.helmet); @@ -412,59 +329,12 @@ public class MainListener implements Listener { return as; } - @SuppressWarnings({"deprecation", "ConstantConditions"}) - private void generateCmdBlock(Location l, ArmorStand as) { - Location loc = as.getLocation(); - int dSlots = NBT.getDisabledSlots(as); - int hand = as.getItemInHand() == null ? 0 : as.getItemInHand().getTypeId(); - int handDmg = as.getItemInHand() == null ? 0 : as.getItemInHand().getDurability(); - int boots = as.getBoots() == null ? 0 : as.getBoots().getTypeId(); - int bootsDmg = as.getBoots() == null ? 0 : as.getBoots().getDurability(); - int legs = as.getLeggings() == null ? 0 : as.getLeggings().getTypeId(); - int legsDmg = as.getLeggings() == null ? 0 : as.getLeggings().getDurability(); - int chest = as.getChestplate() == null ? 0 : as.getChestplate().getTypeId(); - int chestDmg = as.getChestplate() == null ? 0 : as.getChestplate().getDurability(); - int helm = as.getHelmet() == null ? 0 : as.getHelmet().getTypeId(); - int helmDmg = as.getHelmet() == null ? 0 : as.getHelmet().getDurability(); - EulerAngle he = as.getHeadPose(); - EulerAngle ll = as.getLeftLegPose(); - EulerAngle rl = as.getRightLegPose(); - EulerAngle la = as.getLeftArmPose(); - EulerAngle ra = as.getRightArmPose(); - EulerAngle bo = as.getBodyPose(); - String cmd = - "summon ArmorStand " + Utils.twoDec(loc.getX()) + " " + Utils.twoDec(loc.getY()) + " " + Utils.twoDec(loc.getZ()) + " {" - + (as.getMaxHealth() != 20 ? "Attributes:[{Name:\"generic.maxHealth\", Base:" + as.getMaxHealth() + "}]," : "") - + (as.isVisible() ? "" : "Invisible:1,") - + (as.hasBasePlate() ? "" : "NoBasePlate:1,") - + (as.hasGravity() ? "" : "NoGravity:1,") - + (as.hasArms() ? "ShowArms:1," : "") - + (as.isSmall() ? "Small:1," : "") - + (NBT.isInvulnerable(as) ? "Invulnerable:1," : "") - + (dSlots == 0 ? "" : ("DisabledSlots:" + dSlots + ",")) - + (as.isCustomNameVisible() ? "CustomNameVisible:1," : "") - + (as.getCustomName() == null ? "" : ("CustomName:\"" + as.getCustomName() + "\",")) - + (loc.getYaw() == 0F ? "" : ("Rotation:[" + Utils.twoDec(loc.getYaw()) + "f],")) - + (hand == 0 && boots == 0 && legs == 0 && chest == 0 && helm == 0 ? "" : ( - "Equipment:[" - + "{id:" + hand + ",Damage:" + handDmg + NBT.getItemStackTags(as.getItemInHand()) + "}," - + "{id:" + boots + ",Damage:" + bootsDmg + NBT.getItemStackTags(as.getBoots()) + "}," - + "{id:" + legs + ",Damage:" + legsDmg + NBT.getItemStackTags(as.getLeggings()) + "}," - + "{id:" + chest + ",Damage:" + chestDmg + NBT.getItemStackTags(as.getChestplate()) + "}," - + "{id:" + helm + ",Damage:" + helmDmg + NBT.getItemStackTags(as.getHelmet()) + NBT.skullOwner(as.getHelmet()) + "}],")) - + "Pose:{" - + (bo.equals(zero) ? "" : ("Body:[" + Utils.angle(bo.getX()) + "f," + Utils.angle(bo.getY()) + "f," + Utils.angle(bo.getZ()) + "f],")) - + (he.equals(zero) ? "" : ("Head:[" + Utils.angle(he.getX()) + "f," + Utils.angle(he.getY()) + "f," + Utils.angle(he.getZ()) + "f],")) - + (ll.equals(zero) ? "" : ("LeftLeg:[" + Utils.angle(ll.getX()) + "f," + Utils.angle(ll.getY()) + "f," + Utils.angle(ll.getZ()) + "f],")) - + (rl.equals(zero) ? "" : ("RightLeg:[" + Utils.angle(rl.getX()) + "f," + Utils.angle(rl.getY()) + "f," + Utils.angle(rl.getZ()) + "f],")) - + (la.equals(zero) ? "" : ("LeftArm:[" + Utils.angle(la.getX()) + "f," + Utils.angle(la.getY()) + "f," + Utils.angle(la.getZ()) + "f],")) - + "RightArm:[" + Utils.angle(ra.getX()) + "f," + Utils.angle(ra.getY()) + "f," + Utils.angle(ra.getZ()) + "f]}}"; - Block b = l.getBlock(); - b.setType(Material.COMMAND); - b.setData((byte) 0); - CommandBlock cb = (CommandBlock) b.getState(); - cb.setCommand(cmd); - cb.update(); + @EventHandler + public void onBlockBreak(BlockBreakEvent event) { + Block b = event.getBlock(); + if((b.getType() == Material.SKULL && b.hasMetadata("protected")) || (b.getType() == Material.SIGN_POST && b.hasMetadata("armorStand"))) { + event.setCancelled(true); + } } @SuppressWarnings("deprecation") @@ -493,6 +363,7 @@ public class MainListener implements Listener { } else if(b.hasMetadata("setSkull")) { if(MC_USERNAME_PATTERN.matcher(input).matches()) { final String name = input; + b.setMetadata("protected", new FixedMetadataValue(plugin, true)); b.setType(Material.SKULL); final Skull s = (Skull) b.getState(); s.setSkullType(SkullType.PLAYER); @@ -508,13 +379,39 @@ public class MainListener implements Listener { if (ok) { s.setOwner(name); s.update(); - as.setHelmet(b.getDrops().iterator().next()); - event.getPlayer().sendMessage(ChatColor.GREEN + Config.appliedHead + ChatColor.GOLD + " " + name); + new BukkitRunnable() { + int n = 0; + ItemStack skull; + @Override + public void run() { + if(++n > 20) { + this.cancel(); + event.getPlayer().sendMessage(ChatColor.RED + Config.headFailed); + b.setType(Material.AIR); + b.setData((byte) 0); + b.removeMetadata("protected", plugin); + return; + } + skull = b.getDrops().iterator().next(); + if(skull.getType() == Material.SKULL_ITEM && skull.getData().getData() == (byte) 3) { + SkullMeta meta = (SkullMeta) skull.getItemMeta(); + if(meta.hasOwner() && meta.getOwner().equalsIgnoreCase(name)) { + as.setHelmet(skull); + event.getPlayer().sendMessage(ChatColor.GREEN + Config.appliedHead + ChatColor.GOLD + " " + name); + b.setType(Material.AIR); + b.setData((byte) 0); + b.removeMetadata("protected", plugin); + this.cancel(); + } + } + } + }.runTaskTimer(plugin, 10L, 10L); } else { event.getPlayer().sendMessage(ChatColor.RED + Config.noHead + ChatColor.GOLD + " " + name); + b.setType(Material.AIR); + b.setData((byte) 0); + b.removeMetadata("protected", plugin); } - b.setType(Material.AIR); - b.setData((byte) 0); } }.runTask(plugin); } @@ -534,42 +431,6 @@ public class MainListener implements Listener { } } } - - @SuppressWarnings("deprecation") - private void setName(Player p, ArmorStand as) { - Block b = Utils.findAnAirBlock(p.getLocation()); - if(b == null) { - p.sendMessage(ChatColor.RED + Config.noAirError); - return; - } - if(!checkPermission(p, b)) { - p.sendMessage(ChatColor.RED + Config.wgNoPerm); - return; - } - b.setData((byte) 0); - b.setType(Material.SIGN_POST); - Utils.openSign(p, b); - b.setMetadata("armorStand", new FixedMetadataValue(plugin, as.getUniqueId())); - b.setMetadata("setName", new FixedMetadataValue(plugin, true)); - } - - @SuppressWarnings("deprecation") - private void setPlayerSkull(Player p, ArmorStand as) { - Block b = Utils.findAnAirBlock(p.getLocation()); - if(b == null) { - p.sendMessage(ChatColor.RED + Config.noAirError); - return; - } - if(!checkPermission(p, b)) { - p.sendMessage(ChatColor.RED + Config.wgNoPerm); - return; - } - b.setData((byte) 0); - b.setType(Material.SIGN_POST); - Utils.openSign(p, b); - b.setMetadata("armorStand", new FixedMetadataValue(plugin, as.getUniqueId())); - b.setMetadata("setSkull", new FixedMetadataValue(plugin, true)); - } private ArmorStand getArmorStand(Block b) { UUID uuid = null; @@ -588,48 +449,5 @@ public class MainListener implements Listener { } return null; } - - private static boolean checkPermission(Player player, Block block) { - - // Check PlotSquared - Location loc = block.getLocation(); - if (PlotSquaredHook.api != null) { - if (PlotSquaredHook.isPlotWorld(loc)) { - return PlotSquaredHook.checkPermission(player, loc); - } - } - - // check WorldGuard - if(Config.worldGuardPlugin != null) { - return Config.worldGuardPlugin.canBuild(player, block); - } - - // Use standard permission checking (will support basically any plugin) - BlockBreakEvent myBreak = new BlockBreakEvent(block, player); - Bukkit.getServer().getPluginManager().callEvent(myBreak); - boolean hasPerm = !myBreak.isCancelled(); - BlockPlaceEvent place = new BlockPlaceEvent(block, block.getState(), block, null, player, true); - Bukkit.getServer().getPluginManager().callEvent(place); - if (place.isCancelled()) { - hasPerm = false; - } - return hasPerm; - } - - private static boolean playerHasPermission(Player p, Block b, ArmorStandTool tool) { - if(tool != null && !p.isOp() && (!Utils.hasPermissionNode(p, "astools.use") - ||(ArmorStandTool.SAVE == tool && !Utils.hasPermissionNode(p, "astools.cmdblock")) - ||(ArmorStandTool.CLONE == tool && !Utils.hasPermissionNode(p, "astools.clone")))) { - p.sendMessage(ChatColor.RED + Config.noPerm); - return false; - } - return checkPermission(p, b); - } - - void pickUpArmorStand(ArmorStand as, Player p, boolean newlySummoned) { - plugin.carryingArmorStand.put(p.getUniqueId(), as); - if(newlySummoned) return; - as.setMetadata("startLoc", new FixedMetadataValue(plugin, as.getLocation())); - } } diff --git a/src/com/gmail/St3venAU/plugins/ArmorStandTools/Utils.java b/src/com/gmail/St3venAU/plugins/ArmorStandTools/Utils.java index 7d3d295..488b807 100644 --- a/src/com/gmail/St3venAU/plugins/ArmorStandTools/Utils.java +++ b/src/com/gmail/St3venAU/plugins/ArmorStandTools/Utils.java @@ -6,10 +6,12 @@ import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.util.Vector; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; +import java.util.Arrays; import java.util.Collection; class Utils { @@ -18,7 +20,7 @@ class Utils { static boolean containsItems(Collection items) { for(ItemStack i : items) { - if(items.contains(i)) { + if(ArmorStandTool.get(i) != null) { return true; } } @@ -159,4 +161,11 @@ class Utils { return l.getY() < 255 && l.getBlock().getType() == Material.AIR ? l.getBlock() : null; } + static ItemStack setLore(ItemStack is, String... lore) { + ItemMeta meta = is.getItemMeta(); + meta.setLore(Arrays.asList(lore)); + is.setItemMeta(meta); + return is; + } + } diff --git a/src/config.yml b/src/config.yml index 61f67d1..23af7b9 100644 --- a/src/config.yml +++ b/src/config.yml @@ -1,4 +1,4 @@ -# Armor Stand Tools v1.7 +# Armor Stand Tools v2.0 # # by St3venAU (St3venAU@gmail.com) # @@ -7,6 +7,7 @@ # - Name armor stands # - Toggle: Gravity, Visibility, Arms, Base, Size, Invulnerability, Equipment Lock # - Manipulate the position of the Head, Body, Arms and Legs +# - Full control over armor stand's inventory (armor & item in hand) # - Clone armor stand tool # - Create command block tool: Creates a command block with the command that will summon this # armor stand in its current state diff --git a/src/language.yml b/src/language.yml index 22e744a..e63595e 100644 --- a/src/language.yml +++ b/src/language.yml @@ -18,12 +18,11 @@ #################### invReturned: 'Inventory contents returned' asDropped: 'Armor stand dropped' -asVisible: 'Armor stand visible' +asVisible: 'Visible' isTrue: 'True' isFalse: 'False' -asCloned: 'Armor stand cloned' carrying: 'Carrying armor stand. Click to drop.' -noPerm: 'You do not have permission to use this tool' +generalNoPerm: 'No permission for this tool and/or region' cbCreated: 'Command block created' size: 'Size' small: 'Small' @@ -37,6 +36,7 @@ invul: 'Invulnerability' equip: 'Equipment' locked: 'Locked' unLocked: 'Un-Locked' +currently: 'Currently' notConsole: 'This command can not be run from console' giveMsg1: 'Given armor stand tools. L-click any tool to cycle through tools.' giveMsg2: 'Run this command again to return your inventory.' @@ -47,13 +47,30 @@ pleaseWait: 'Please wait, this may take a few seconds...' appliedHead: 'Applied the head of player' noHead: 'No player head found for player' invalidName: 'is not a valid minecraft username' -wgNoPerm: 'You do not have permission to alter an armor stand in this region' +wgNoPerm: 'No permission to alter an armor stand in this region' +headFailed: 'Failed to apply the player head. Try again.' noCommandPerm: 'You do not have permission to use this command' # ############################# # Tool names & descriptions # ############################# tool: + summon: + name: 'Summon Armor Stand' + lore: + - 'R-Click to summon an armor stand and pick it up' + - 'Any click will drop it' + gui: + name: 'GUI Multi-Tool' + lore: + - 'R-Click armor stand to open a GUI to tweak' + - 'the attributes of the armor stand or change' + - 'its armor and items' + rotat: + name: 'Rotation' + lore: + - 'R-Click armor stand to change its Rotation' + - 'Value depends on how high up the body you click' headX: name: 'Head X' lore: @@ -114,31 +131,6 @@ tool: lore: - 'R-Click armor stand to move +0.1 Z' - 'Crouch R-Click for -0.1 Z' - rotat: - name: 'Rotation' - lore: - - 'R-Click armor stand to change its Rotation' - - 'Value depends on how high up the body you click' - invis: - name: 'Toggle Visibility' - lore: - - 'R-Click armor stand to toggle its visibility' - summon: - name: 'Summon Armor Stand' - lore: - - 'R-Click to summon an armor stand and pick it up' - - 'Any click will drop it' - - 'To change summoned armor stand defaults, edit config.yml' - clone: - name: 'Clone' - lore: - - 'R-Click armor stand to pick up a clone of it' - - 'Any click will drop it' - save: - name: 'Create Command Block' - lore: - - 'R-Click armor stand to create command block' - - 'with a summon command for this armor stand' lLegX: name: 'Left Leg X' lore: @@ -184,45 +176,43 @@ tool: lore: - 'R-Click armor stand to change Body Z' - 'Value depends on how high up the body you click' - size: - name: 'Toggle Size' - lore: - - 'R-Click armor stand to toggle its size' - base: - name: 'Toggle Base' - lore: - - 'R-Click armor stand to toggle its base' - grav: - name: 'Toggle Gravity' - lore: - - 'R-Click armor stand to toggle its gravity' - arms: - name: 'Toggle Arms' - lore: - - 'R-Click armor stand to toggle its arms' - name: - name: 'Set Name' - lore: - - 'R-Click armor stand to set its name' - - 'Standard color codes accepted' - slots: - name: 'Toggle Equipment Lock' - lore: - - 'R-Click armor stand to toggle equipment lock' - - 'When equipment is locked, players can not take or add equipment' - pHead: - name: 'Give a Player Head' - lore: - - 'R-Click armor stand and specify a player name to' - - 'give it that players head' - - '(Will not work if used multiple times too fast)' - invul: - name: 'Toggle Invulnerability' - lore: - - 'R-Click armor stand to toggle invulnerability' - - 'Note: Creative mode players can break invulnerable armor stands' - move: + gui_move: name: 'Pick Up (Move)' lore: - - 'R-Click armor stand to pick it up and move it' - - 'Any click will drop it again' \ No newline at end of file + - 'Pick up this armor stand to move it' + gui_clone: + name: 'Clone' + lore: + - 'Clone this armor stand and pick it up' + gui_save: + name: 'Create Command Block' + lore: + - 'Create command block to' + - 'summon this armor stand' + gui_invis: + name: 'Toggle Visibility' + lore: + gui_size: + name: 'Toggle Size' + lore: + gui_base: + name: 'Toggle Base' + lore: + gui_grav: + name: 'Toggle Gravity' + lore: + gui_arms: + name: 'Toggle Arms' + lore: + gui_name: + name: 'Change Name' + lore: + gui_slots: + name: 'Toggle Equipment Lock' + lore: + gui_pHead: + name: 'Give Player Head' + lore: + gui_invul: + name: 'Toggle Invulnerability' + lore: \ No newline at end of file diff --git a/src/plugin.yml b/src/plugin.yml index e9e59b5..10d7bf0 100644 --- a/src/plugin.yml +++ b/src/plugin.yml @@ -1,6 +1,6 @@ main: com.gmail.St3venAU.plugins.ArmorStandTools.Main name: ArmorStandTools -version: 1.7 +version: 2.0 author: St3venAU description: Armor stand manipulation tools softdepend: [WorldGuard, PlotSquared]