From da41151402a13b20fd2b4748da00ab9330326936 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 25 Mar 2017 13:45:17 +0100 Subject: [PATCH] Added shift-click to sell stack Only works when a player does not have an axe in one of his hands. If he has, the shop will be broken/removed (if he has permission). Closes #84 --- .../listeners/ChestProtectListener.java | 5 +-- .../listeners/ShopInteractListener.java | 40 ++++++++++--------- .../de/epiceric/shopchest/utils/Utils.java | 17 ++++++++ 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/main/java/de/epiceric/shopchest/listeners/ChestProtectListener.java b/src/main/java/de/epiceric/shopchest/listeners/ChestProtectListener.java index 6accaa6..a6cec8c 100644 --- a/src/main/java/de/epiceric/shopchest/listeners/ChestProtectListener.java +++ b/src/main/java/de/epiceric/shopchest/listeners/ChestProtectListener.java @@ -87,10 +87,7 @@ public class ChestProtectListener implements Listener { final Shop shop = shopUtils.getShop(e.getBlock().getLocation()); Player p = e.getPlayer(); - ItemStack item = Utils.getPreferredItemInHand(p); - List axes = Arrays.asList(Material.WOOD_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLD_AXE, Material.DIAMOND_AXE); - - if (p.isSneaking() && item != null && axes.contains(item.getType())) { + if (p.isSneaking() && Utils.hasAxeInHand(p)) { plugin.debug(String.format("%s tries to break %s's shop (#%d)", p.getName(), shop.getVendor().getName(), shop.getID())); if (shop.getShopType() == Shop.ShopType.ADMIN) { diff --git a/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java b/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java index 6405f7e..110c28a 100644 --- a/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java +++ b/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java @@ -243,10 +243,8 @@ public class ShopInteractListener implements Listener { if (shopUtils.isShop(b.getLocation())) { Shop shop = shopUtils.getShop(b.getLocation()); - if (e.getAction() == Action.LEFT_CLICK_BLOCK) { - if (p.isSneaking()) { - return; - } + if (e.getAction() == Action.LEFT_CLICK_BLOCK && p.isSneaking() && Utils.hasAxeInHand(p)) { + return; } if (e.getAction() == Action.RIGHT_CLICK_BLOCK && p.getUniqueId().equals(shop.getVendor().getUniqueId()) && shop.getShopType() != ShopType.ADMIN) { @@ -335,10 +333,10 @@ public class ShopInteractListener implements Listener { if (worldGuardAllowed || p.hasPermission(Permissions.WORLDGUARD_BYPASS)) { if (Utils.getAmount(p.getInventory(), shop.getProduct()) >= shop.getProduct().getAmount()) { - sell(p, shop); + sell(p, shop, p.isSneaking() && !Utils.hasAxeInHand(p)); } else { if (config.auto_calculate_item_amount && Utils.getAmount(p.getInventory(), shop.getProduct()) > 0) { - sell(p, shop); + sell(p, shop, p.isSneaking() && !Utils.hasAxeInHand(p)); } else { p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_ITEMS)); plugin.debug(p.getName() + " doesn't have enough items"); @@ -770,11 +768,17 @@ public class ShopInteractListener implements Listener { * @param executor Player, who executed the command and will sell the product * @param shop Shop, to which the player sells */ - private void sell(Player executor, Shop shop) { + private void sell(Player executor, Shop shop, boolean stack) { plugin.debug(executor.getName() + " is selling (#" + shop.getID() + ")"); - if (econ.getBalance(shop.getVendor()) >= shop.getSellPrice() || shop.getShopType() == ShopType.ADMIN || config.auto_calculate_item_amount) { - int amountForMoney = (int) (shop.getProduct().getAmount() / shop.getSellPrice() * econ.getBalance(shop.getVendor())); + int amount = shop.getProduct().getAmount(); + if (stack) amount = shop.getProduct().getMaxStackSize(); + + double price = shop.getSellPrice(); + if (stack) price = (price / shop.getProduct().getAmount()) * amount; + + if (econ.getBalance(shop.getVendor()) >= price || shop.getShopType() == ShopType.ADMIN || config.auto_calculate_item_amount) { + int amountForMoney = (int) (amount / price * econ.getBalance(shop.getVendor())); plugin.debug("Vendor has enough money for " + amountForMoney + " item(s) (#" + shop.getID() + ")"); @@ -788,37 +792,37 @@ public class ShopInteractListener implements Listener { int amountForItemCount = Utils.getAmount(executor.getInventory(), shop.getProduct()); - if (amountForItemCount == 0 && config.auto_calculate_item_amount) { + if (amountForItemCount == 0) { executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_ITEMS)); return; } ItemStack product = new ItemStack(shop.getProduct()); + if (stack) product.setAmount(amount); + Inventory inventory = chest.getInventory(); int freeSpace = Utils.getFreeSpaceForItem(inventory, product); - int amountForChestSpace = (freeSpace >= product.getAmount() ? product.getAmount() : freeSpace); - - if (amountForChestSpace == 0 && config.auto_calculate_item_amount && shop.getShopType() != ShopType.ADMIN) { + if (freeSpace == 0 && shop.getShopType() != ShopType.ADMIN) { executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CHEST_NOT_ENOUGH_INVENTORY_SPACE)); return; } - int newAmount = product.getAmount(); + int newAmount = amount; if (config.auto_calculate_item_amount) { if (shop.getShopType() == ShopType.ADMIN) newAmount = amountForItemCount; else - newAmount = Math.min(Math.min(amountForMoney, amountForItemCount), amountForChestSpace); + newAmount = Math.min(Math.min(amountForMoney, amountForItemCount), freeSpace); } - if (newAmount > product.getAmount()) newAmount = product.getAmount(); + if (newAmount > amount) newAmount = amount; - double newPrice = (shop.getSellPrice() / product.getAmount()) * newAmount; + double newPrice = (price / amount) * newAmount; - if (freeSpace >= product.getAmount() || (config.auto_calculate_item_amount && freeSpace >= newAmount) || shop.getShopType() == ShopType.ADMIN) { + if (freeSpace >= newAmount || shop.getShopType() == ShopType.ADMIN) { plugin.debug("Chest has enough inventory space for " + freeSpace + " items (#" + shop.getID() + ")"); ItemStack newProduct = new ItemStack(product); diff --git a/src/main/java/de/epiceric/shopchest/utils/Utils.java b/src/main/java/de/epiceric/shopchest/utils/Utils.java index 7aa139a..ff2c59e 100644 --- a/src/main/java/de/epiceric/shopchest/utils/Utils.java +++ b/src/main/java/de/epiceric/shopchest/utils/Utils.java @@ -16,7 +16,9 @@ import javax.xml.bind.DatatypeConverter; import java.lang.reflect.InvocationTargetException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; public class Utils { @@ -217,6 +219,21 @@ public class Utils { } } + /** + * @param p Player to check if he has an axe in one of his hands + * @return Whether a player has an axe in one of his hands + */ + public static boolean hasAxeInHand(Player p) { + List axes = Arrays.asList(Material.WOOD_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLD_AXE, Material.DIAMOND_AXE); + + ItemStack item = getItemInMainHand(p); + if (item == null || !axes.contains(item.getType())) { + item = getItemInOffHand(p); + } + + return item != null && axes.contains(item.getType()); + } + /** * @param className Name of the class * @return Class in {@code net.minecraft.server.[VERSION]} package with the specified name or {@code null} if the class was not found