package com.nisovin.magicspells.spells.buff; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryType.SlotType; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.meta.ItemMeta; import com.nisovin.magicspells.MagicSpells; import com.nisovin.magicspells.spells.BuffSpell; import com.nisovin.magicspells.util.MagicConfig; import com.nisovin.magicspells.util.Util; public class ArmorSpell extends BuffSpell { private boolean permanent; private boolean replace; private ItemStack helmet; private ItemStack chestplate; private ItemStack leggings; private ItemStack boots; private String strHasArmor; private String strLoreText; private Set<String> armored; public ArmorSpell(MagicConfig config, String spellName) { super(config, spellName); permanent = getConfigBoolean("permanent", false); replace = getConfigBoolean("replace", false); strLoreText = ChatColor.translateAlternateColorCodes('&', getConfigString("str-lore-text", "Conjured")); helmet = getItem(getConfigString("helmet", "")); chestplate = getItem(getConfigString("chestplate", "")); leggings = getItem(getConfigString("leggings", "")); boots = getItem(getConfigString("boots", "")); strHasArmor = getConfigString("str-has-armor", "You cannot cast this spell if you are wearing armor."); armored = new HashSet<String>(); } @Override public void initialize() { super.initialize(); if (!permanent) { registerEvents(new ArmorListener()); } } private ItemStack getItem(String s) { if (!s.isEmpty()) { String[] info = s.split(" "); try { // get type and data ItemStack item = Util.getItemStackFromString(info[0]); if (item == null) return null; item.setAmount(1); if (!permanent) { ItemMeta meta = item.getItemMeta(); List<String> lore; if (meta.hasLore()) { lore = meta.getLore(); } else { lore = new ArrayList<String>(); } lore.add(strLoreText); meta.setLore(lore); item.setItemMeta(meta); } // get enchantments (left for backwards compatibility) if (info.length > 1) { for (int i = 1; i < info.length; i++) { String[] enchinfo = info[i].split(":"); Enchantment ench = Util.getEnchantmentType(enchinfo[0]); int lvl = 1; if (enchinfo.length > 1) { lvl = Integer.parseInt(enchinfo[1].toUpperCase().replace(" ", "_")); } if (ench != null) { item.addUnsafeEnchantment(ench, lvl); } } } return item; } catch (NumberFormatException e) { return null; } } else { return null; } } @Override public boolean castBuff(Player player, float power, String[] args) { PlayerInventory inv = player.getInventory(); if (!replace && ((helmet != null && inv.getHelmet() != null) || (chestplate != null && inv.getChestplate() != null) || (leggings != null && inv.getLeggings() != null) || (boots != null && inv.getBoots() != null))) { // error sendMessage(player, strHasArmor); return false; } setArmor(inv); if (!permanent) { armored.add(player.getName()); } return true; } @Override public boolean recastBuff(Player player, float power, String[] args) { return castBuff(player, power, args); } private void setArmor(PlayerInventory inv) { if (helmet != null) { if (replace) inv.setHelmet(null); inv.setHelmet(helmet.clone()); } if (chestplate != null) { if (replace) inv.setChestplate(null); inv.setChestplate(chestplate.clone()); } if (leggings != null) { if (replace) inv.setLeggings(null); inv.setLeggings(leggings.clone()); } if (boots != null) { if (replace) inv.setBoots(null); inv.setBoots(boots.clone()); } } private void removeArmor(PlayerInventory inv) { if (helmet != null && inv.getHelmet() != null && inv.getHelmet().getType() == helmet.getType()) { inv.setHelmet(null); } if (chestplate != null && inv.getChestplate() != null && inv.getChestplate().getType() == chestplate.getType()) { inv.setChestplate(null); } if (leggings != null && inv.getLeggings() != null && inv.getLeggings().getType() == leggings.getType()) { inv.setLeggings(null); } if (boots != null && inv.getBoots() != null && inv.getBoots().getType() == boots.getType()) { inv.setBoots(null); } } class ArmorListener implements Listener { @EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true) public void onEntityDamage(EntityDamageEvent event) { if (event.getEntity() instanceof Player) { Player p = (Player)event.getEntity(); if (isActive(p) && p.getNoDamageTicks() < 10) { addUseAndChargeCost(p); } } } @EventHandler(ignoreCancelled=true) public void onInventoryClick(InventoryClickEvent event) { if (event.getSlotType() == SlotType.ARMOR && event.getWhoClicked() instanceof Player) { Player p = (Player)event.getWhoClicked(); if (isActive(p)) { event.setCancelled(true); } } } @EventHandler public void onPlayerDeath(PlayerDeathEvent event) { Iterator<ItemStack> drops = event.getDrops().iterator(); while (drops.hasNext()) { ItemStack drop = drops.next(); List<String> lore = drop.getItemMeta().getLore(); if (lore != null && lore.size() > 0 && lore.get(lore.size()-1).equals(strLoreText)) { drops.remove(); } } } @EventHandler public void onPlayerRespawn(PlayerRespawnEvent event) { if (isActive(event.getPlayer()) && !isExpired(event.getPlayer())) { final PlayerInventory inv = event.getPlayer().getInventory(); Bukkit.getScheduler().scheduleSyncDelayedTask(MagicSpells.plugin, new Runnable() { public void run() { setArmor(inv); } }); } } @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { if (isActive(event.getPlayer())) { if (cancelOnLogout) { turnOff(event.getPlayer()); } else { removeArmor(event.getPlayer().getInventory()); } } } @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { if (isActive(event.getPlayer())) { if (!isExpired(event.getPlayer())) { setArmor(event.getPlayer().getInventory()); } else { turnOff(event.getPlayer()); } } } } @Override public void turnOffBuff(Player player) { if (armored.remove(player.getName())) { if (player.isOnline()) { PlayerInventory inv = player.getInventory(); removeArmor(inv); } } } @Override protected void turnOff() { for (String name : new HashSet<String>(armored)) { Player p = Bukkit.getPlayerExact(name); if (p != null && p.isOnline()) { turnOff(p); } } } @Override public boolean isActive(Player player) { return armored.contains(player.getName()); } }