/** * Attempt to perform a cauldron recipe. * * @param player * @param world * @param pt */ private void performCauldron(Player player, World world, BlockWorldVector pt) { // Gotta start at a root Y then find our orientation int rootY = pt.getBlockY(); int blockID = plugin.getLocalConfiguration().cauldronSettings.cauldronBlock; // Used to store cauldron blocks -- walls are counted Map<BlockWorldVector, Integer> visited = new HashMap<BlockWorldVector, Integer>(); try { // The following attempts to recursively find adjacent blocks so // that it can find all the blocks used within the cauldron findCauldronContents(world, pt, rootY - 1, rootY, visited); // We want cauldrons of a specific shape and size, and 24 is just // the right number of blocks that the cauldron we want takes up -- // nice and cheap check if (visited.size() != 24) { throw new NotACauldronException("mech.cauldron.too-small"); } // Key is the block ID and the value is the amount Map<Integer, Integer> contents = new HashMap<Integer, Integer>(); // Now we have to ignore cauldron blocks so that we get the real // contents of the cauldron for (Map.Entry<BlockWorldVector, Integer> entry : visited.entrySet()) { if (entry.getValue() != blockID) { if (!contents.containsKey(entry.getValue())) { contents.put(entry.getValue(), 1); } else { contents.put(entry.getValue(), contents.get(entry.getValue()) + 1); } } } // Find the recipe CauldronCookbook.Recipe recipe = recipes.find(contents); if (recipe != null) { String[] groups = recipe.getGroups(); if (groups != null) { boolean found = false; for (@SuppressWarnings("unused") String group : groups) { found = true; break; // TODO: Add an isInGroup method /* * if (player.isInGroup(group)) { found = true; break; } */ } if (!found) { player.sendMessage(ChatColor.DARK_RED + "Doesn't seem as if you have the ability..."); return; } } player.sendMessage( ChatColor.GOLD + "In a poof of smoke, you've made " + recipe.getName() + "."); List<Integer> ingredients = new ArrayList<Integer>(recipe.getIngredients()); List<BlockWorldVector> removeQueue = new ArrayList<BlockWorldVector>(); // Get rid of the blocks in world for (Map.Entry<BlockWorldVector, Integer> entry : visited.entrySet()) { // This is not a fast operation, but we should not have // too many ingredients if (ingredients.contains(entry.getValue())) { // Some blocks need to removed first otherwise they will // drop an item, so let's remove those first // if // (!BlockID.isBottomDependentBlock(entry.getValue())) { // removeQueue.add(entry.getKey()); // } else { world .getBlockAt( entry.getKey().getBlockX(), entry.getKey().getBlockY(), entry.getKey().getBlockZ()) .setType(Material.AIR); // } ingredients.remove(entry.getValue()); } } for (BlockWorldVector v : removeQueue) { world.getBlockAt(v.getBlockX(), v.getBlockY(), v.getBlockZ()).setType(Material.AIR); } // Give results for (Integer id : recipe.getResults()) { HashMap<Integer, ItemStack> map = player.getInventory().addItem(new ItemStack(id, 1)); for (Entry<Integer, ItemStack> i : map.entrySet()) { world.dropItem(player.getLocation(), i.getValue()); } } // Didn't find a recipe } else { player.sendMessage(ChatColor.RED + "Hmm, this doesn't make anything..."); } } catch (NotACauldronException ignored) { } }
/** * Attempt to perform a cauldron recipe. * * @param pt * @param player * @param recipes */ private void performCauldron(BlockVector pt, Player player) { // Gotta start at a root Y then find our orientation int rootY = pt.getBlockY(); // Used to store cauldron blocks -- walls are counted Map<BlockVector, CraftBookItem> visited = new HashMap<BlockVector, CraftBookItem>(); World world = player.getWorld(); try { // The following attempts to recursively find adjacent blocks so // that it can find all the blocks used within the cauldron findCauldronContents(world, pt, rootY - 1, rootY, visited); // We want cauldrons of a specific shape and size, and 24 is just // the right number of blocks that the cauldron we want takes up -- // nice and cheap check if (visited.size() != 24) { throw new NotACauldronException("Cauldron is too small"); } // Key is the block ID and the value is the amount Map<CraftBookItem, Integer> contents = new HashMap<CraftBookItem, Integer>(); // Now we have to ignore stone blocks so that we get the real // contents of the cauldron for (Map.Entry<BlockVector, CraftBookItem> entry : visited.entrySet()) { if (entry.getValue().id() != BlockType.STONE) { if (!contents.containsKey(entry.getValue())) { contents.put(entry.getValue(), 1); } else { contents.put(entry.getValue(), contents.get(entry.getValue()) + 1); } } } // Find the recipe CauldronRecipe recipe = recipes.find(contents); if (recipe != null) { String[] groups = recipe.getGroups(); if (groups != null) { boolean found = false; for (String group : groups) { if (player.isInGroup(group)) { found = true; break; } } if (!found) { player.sendMessage(Colors.Red + "Doesn't seem as if you have the ability..."); return; } } player.sendMessage( Colors.Gold + "In a poof of smoke, you've made " + recipe.getName() + "."); List<CraftBookItem> ingredients = new ArrayList<CraftBookItem>(recipe.getIngredients()); List<BlockVector> removeQueue = new ArrayList<BlockVector>(); // Get rid of the blocks in world for (Map.Entry<BlockVector, CraftBookItem> entry : visited.entrySet()) { // This is not a fast operation, but we should not have // too many ingredients if (ingredients.contains(entry.getValue())) { // Some blocks need to removed first otherwise they will // drop an item, so let's remove those first if (!BlockType.isBottomDependentBlock(entry.getValue().id())) { removeQueue.add(entry.getKey()); } else { CraftBook.setBlockID(world, entry.getKey(), 0); } ingredients.remove(entry.getValue()); } } for (BlockVector v : removeQueue) { CraftBook.setBlockID(world, v, 0); } // Give results for (CraftBookItem cbitem : recipe.getResults()) { Item item = new Item(cbitem.id(), 1, -1, cbitem.color()); if (cbitem.hasEnchantments()) { for (int i = 0; i < cbitem.enchantments().length; i++) { CraftBookEnchantment cbenchant = cbitem.enchantment(i); // since this is from a server created recipe we can assume it is allowed // if(!cbenchant.enchantment().allowed) // continue; Enchantment enchant = new Enchantment( Enchantment.Type.fromId(cbenchant.enchantment().getId()), cbenchant.level()); if (!enchant.isValid()) continue; item.addEnchantment(enchant); } } player.giveItem(item); } // Didn't find a recipe } else { player.sendMessage(Colors.Red + "Hmm, this doesn't make anything..."); } } catch (NotACauldronException e) { } }