001 package org.bukkit.command.defaults; 002 003 import java.util.ArrayList; 004 import java.util.Collections; 005 import java.util.List; 006 import java.util.Map; 007 008 import org.apache.commons.lang.Validate; 009 import org.apache.commons.lang.WordUtils; 010 import com.google.common.collect.ImmutableList; 011 012 import org.bukkit.Bukkit; 013 import org.bukkit.ChatColor; 014 import org.bukkit.Material; 015 import org.bukkit.command.Command; 016 import org.bukkit.command.CommandSender; 017 import org.bukkit.enchantments.Enchantment; 018 import org.bukkit.entity.Player; 019 import org.bukkit.inventory.ItemStack; 020 import org.bukkit.util.StringUtil; 021 022 public class EnchantCommand extends VanillaCommand { 023 private static final List<String> ENCHANTMENT_NAMES = new ArrayList<String>(); 024 025 public EnchantCommand() { 026 super("enchant"); 027 this.description = "Adds enchantments to the item the player is currently holding. Specify 0 for the level to remove an enchantment. Specify force to ignore normal enchantment restrictions"; 028 this.usageMessage = "/enchant <player> <enchantment> [level|max|0] [force]"; 029 this.setPermission("bukkit.command.enchant"); 030 } 031 032 @Override 033 public boolean execute(CommandSender sender, String commandLabel, String[] args) { 034 if (!testPermission(sender)) return true; 035 if (args.length < 2) { 036 sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); 037 return false; 038 } 039 040 boolean force = false; 041 if (args.length > 2) { 042 force = args[args.length > 3 ? 3 : 2].equalsIgnoreCase("force"); 043 } 044 045 Player player = Bukkit.getPlayerExact(args[0]); 046 if (player == null) { 047 sender.sendMessage("Can't find player " + args[0]); 048 } else { 049 ItemStack item = player.getItemInHand(); 050 if (item.getType() == Material.AIR) { 051 sender.sendMessage("The player isn't holding an item"); 052 } else { 053 String itemName = item.getType().toString().replaceAll("_", " "); 054 itemName = WordUtils.capitalizeFully(itemName); 055 056 Enchantment enchantment = getEnchantment(args[1].toUpperCase()); 057 if (enchantment == null) { 058 sender.sendMessage(String.format("Enchantment does not exist: %s", args[1])); 059 } else { 060 String enchantmentName = enchantment.getName().replaceAll("_", " "); 061 enchantmentName = WordUtils.capitalizeFully(enchantmentName); 062 063 if (!force && !enchantment.canEnchantItem(item)) { 064 sender.sendMessage(String.format("%s cannot be applied to %s", enchantmentName, itemName)); 065 } else { 066 int level = 1; 067 if (args.length > 2) { 068 Integer integer = getInteger(args[2]); 069 int minLevel = enchantment.getStartLevel(); 070 int maxLevel = force ? Short.MAX_VALUE : enchantment.getMaxLevel(); 071 072 if (integer != null) { 073 if (integer == 0) { 074 item.removeEnchantment(enchantment); 075 Command.broadcastCommandMessage(sender, String.format("Removed %s on %s's %s", enchantmentName, player.getName(), itemName)); 076 return true; 077 } 078 079 if (integer < minLevel || integer > maxLevel) { 080 sender.sendMessage(String.format("Level for enchantment %s must be between %d and %d", enchantmentName, minLevel, maxLevel)); 081 sender.sendMessage("Specify 0 for level to remove an enchantment"); 082 return true; 083 } 084 085 level = integer; 086 } 087 088 if ("max".equals(args[2])) { 089 level = maxLevel; 090 } 091 } 092 093 Map<Enchantment, Integer> enchantments = item.getEnchantments(); 094 boolean conflicts = false; 095 096 if (!force && !enchantments.isEmpty()) { // TODO: Improve this to use a "hasEnchantments" call 097 for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) { 098 Enchantment enchant = entry.getKey(); 099 100 if (enchant.equals(enchantment)) continue; 101 if (enchant.conflictsWith(enchantment)) { 102 sender.sendMessage(String.format("Can't apply the enchantment %s on an item with the enchantment %s", enchantmentName, WordUtils.capitalizeFully(enchant.getName().replaceAll("_", " ")))); 103 conflicts = true; 104 break; 105 } 106 } 107 } 108 109 if (!conflicts) { 110 item.addUnsafeEnchantment(enchantment, level); 111 112 Command.broadcastCommandMessage(sender, String.format("Applied %s (Lvl %d) on %s's %s", enchantmentName, level, player.getName(), itemName), false); 113 sender.sendMessage(String.format("Enchanting succeeded, applied %s (Lvl %d) onto your %s", enchantmentName, level, itemName)); 114 } 115 } 116 } 117 } 118 } 119 return true; 120 } 121 122 @Override 123 public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { 124 Validate.notNull(sender, "Sender cannot be null"); 125 Validate.notNull(args, "Arguments cannot be null"); 126 Validate.notNull(alias, "Alias cannot be null"); 127 128 if (args.length == 1) { 129 return super.tabComplete(sender, alias, args); 130 } 131 132 if (args.length == 2) { 133 return StringUtil.copyPartialMatches(args[1], ENCHANTMENT_NAMES, new ArrayList<String>(ENCHANTMENT_NAMES.size())); 134 } 135 136 if (args.length == 3 || args.length == 4) { 137 if (!args[args.length - 2].equalsIgnoreCase("force")) { 138 return ImmutableList.of("force"); 139 } 140 } 141 142 return ImmutableList.of(); 143 } 144 145 private Enchantment getEnchantment(String lookup) { 146 Enchantment enchantment = Enchantment.getByName(lookup); 147 148 if (enchantment == null) { 149 Integer id = getInteger(lookup); 150 if (id != null) { 151 enchantment = Enchantment.getById(id); 152 } 153 } 154 155 return enchantment; 156 } 157 158 public static void buildEnchantments() { 159 if (!ENCHANTMENT_NAMES.isEmpty()) { 160 throw new IllegalStateException("Enchantments have already been built!"); 161 } 162 163 for (Enchantment enchantment : Enchantment.values()) { 164 ENCHANTMENT_NAMES.add(enchantment.getName()); 165 } 166 167 Collections.sort(ENCHANTMENT_NAMES); 168 } 169 }