From 4bf5472e61c447163dc4220e019cea654b16b1d2 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 16 Aug 2016 15:06:26 +0200 Subject: [PATCH] Added way to auto calculate item amount You can find an explanation here: - https://www.spigotmc.org/threads/shopchest.87948/page-15#post-1820672 - In the configuration file --- .../de/epiceric/shopchest/config/Config.java | 4 + .../shopchest/event/ShopBuySellEvent.java | 20 +- .../listeners/ShopInteractListener.java | 201 ++++++++++-------- .../de/epiceric/shopchest/utils/Utils.java | 60 ++++++ src/main/resources/config.yml | 10 + 5 files changed, 205 insertions(+), 90 deletions(-) diff --git a/src/main/java/de/epiceric/shopchest/config/Config.java b/src/main/java/de/epiceric/shopchest/config/Config.java index 827cb04..4607089 100644 --- a/src/main/java/de/epiceric/shopchest/config/Config.java +++ b/src/main/java/de/epiceric/shopchest/config/Config.java @@ -103,6 +103,9 @@ public class Config { */ public boolean remove_shop_on_error; + /** Whether the item amount should be calculated to fit the available money or inventory space **/ + public boolean auto_calculate_item_amount; + /** Amount the hologram should be lifted **/ public double two_line_hologram_lift; @@ -276,6 +279,7 @@ public class Config { database_type = Database.DatabaseType.valueOf(plugin.getConfig().getString("database.type")); minimum_prices = (plugin.getConfig().getConfigurationSection("minimum-prices") == null) ? new HashSet() : plugin.getConfig().getConfigurationSection("minimum-prices").getKeys(true); allow_broken_items = plugin.getConfig().getBoolean("allow-broken-items"); + auto_calculate_item_amount = plugin.getConfig().getBoolean("auto-calculate-item-amount"); shopLimits_group = (plugin.getConfig().getConfigurationSection("shop-limits.group") == null) ? new HashSet() : plugin.getConfig().getConfigurationSection("shop-limits.group").getKeys(true); shopLimits_player = (plugin.getConfig().getConfigurationSection("shop-limits.player") == null) ? new HashSet() : plugin.getConfig().getConfigurationSection("shop-limits.player").getKeys(true); blacklist = (plugin.getConfig().getStringList("blacklist") == null) ? new ArrayList() : plugin.getConfig().getStringList("blacklist"); diff --git a/src/main/java/de/epiceric/shopchest/event/ShopBuySellEvent.java b/src/main/java/de/epiceric/shopchest/event/ShopBuySellEvent.java index e36cc30..b365c99 100644 --- a/src/main/java/de/epiceric/shopchest/event/ShopBuySellEvent.java +++ b/src/main/java/de/epiceric/shopchest/event/ShopBuySellEvent.java @@ -11,12 +11,16 @@ public class ShopBuySellEvent extends ShopEvent implements Cancellable { private Player player; private Shop shop; private Type type; + private int newAmount; + private double newPrice; private boolean cancelled; - public ShopBuySellEvent(Player player, Shop shop, Type type) { + public ShopBuySellEvent(Player player, Shop shop, Type type, int newAmount, double newPrice) { this.player = player; this.shop = shop; this.type = type; + this.newAmount = newAmount; + this.newPrice = newPrice; } @Override @@ -31,6 +35,20 @@ public class ShopBuySellEvent extends ShopEvent implements Cancellable { return type; } + /** + * @return The amount which might be modified because of automatic item amount calculation + */ + public int getNewAmount() { + return newAmount; + } + + /** + * @return The price which might be modified because of automatic item amount calculation + */ + public double getNewPrice() { + return newPrice; + } + @Override public Player getPlayer() { return player; diff --git a/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java b/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java index c2389df..49a27e8 100644 --- a/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java +++ b/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java @@ -1,6 +1,7 @@ package de.epiceric.shopchest.listeners; import de.epiceric.shopchest.ShopChest; +import de.epiceric.shopchest.config.Config; import de.epiceric.shopchest.config.Regex; import de.epiceric.shopchest.event.ShopBuySellEvent; import de.epiceric.shopchest.event.ShopCreateEvent; @@ -48,6 +49,7 @@ public class ShopInteractListener implements Listener { private Economy econ; private Database database; private ShopUtils shopUtils; + private Config config; public ShopInteractListener(ShopChest plugin) { this.plugin = plugin; @@ -55,6 +57,7 @@ public class ShopInteractListener implements Listener { this.econ = plugin.getEconomy(); this.database = plugin.getShopDatabase(); this.shopUtils = plugin.getShopUtils(); + this.config = plugin.getShopChestConfig(); } @EventHandler(priority = EventPriority.HIGH) @@ -185,8 +188,12 @@ public class ShopInteractListener implements Listener { if (Utils.getAmount(c.getInventory(), shop.getProduct()) >= shop.getProduct().getAmount()) { buy(p, shop); } else { - p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.OUT_OF_STOCK)); - plugin.debug("Shop is out of stock"); + if (config.auto_calculate_item_amount && Utils.getAmount(c.getInventory(), shop.getProduct()) > 0) { + buy(p, shop); + } else { + p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.OUT_OF_STOCK)); + plugin.debug("Shop is out of stock"); + } } } } else { @@ -222,8 +229,12 @@ public class ShopInteractListener implements Listener { if (Utils.getAmount(p.getInventory(), shop.getProduct()) >= shop.getProduct().getAmount()) { sell(p, shop); } else { - p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_ITEMS)); - plugin.debug(p.getName() + " doesn't have enough items"); + if (config.auto_calculate_item_amount && Utils.getAmount(p.getInventory(), shop.getProduct()) > 0) { + sell(p, shop); + } else { + p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_ITEMS)); + plugin.debug(p.getName() + " doesn't have enough items"); + } } } else { p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_SELL)); @@ -262,7 +273,7 @@ public class ShopInteractListener implements Listener { plugin.debug(executor.getName() + " is creating new shop..."); int id = database.getNextFreeID(); - double creationPrice = (shopType == ShopType.NORMAL) ? plugin.getShopChestConfig().shop_creation_price_normal : plugin.getShopChestConfig().shop_creation_price_admin; + double creationPrice = (shopType == ShopType.NORMAL) ? config.shop_creation_price_normal : config.shop_creation_price_admin; ShopCreateEvent event = new ShopCreateEvent(executor, Shop.createImaginaryShop(executor, product, location, buyPrice, sellPrice,shopType), creationPrice); Bukkit.getPluginManager().callEvent(event); @@ -410,78 +421,78 @@ public class ShopInteractListener implements Listener { */ private void buy(Player executor, Shop shop) { plugin.debug(executor.getName() + " is buying (#" + shop.getID() + ")"); - if (econ.getBalance(executor) >= shop.getBuyPrice()) { - plugin.debug(executor.getName() + " has enough money (#" + shop.getID() + ")"); + if (econ.getBalance(executor) >= shop.getBuyPrice() || config.auto_calculate_item_amount) { + + int amountForMoney = (int) (shop.getProduct().getAmount() / shop.getBuyPrice() * econ.getBalance(executor)); + + if (amountForMoney == 0 && config.auto_calculate_item_amount) { + executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_MONEY)); + return; + } + + plugin.debug(executor.getName() + " has enough money for " + amountForMoney + " item(s) (#" + shop.getID() + ")"); Block b = shop.getLocation().getBlock(); Chest c = (Chest) b.getState(); - HashMap slotFree = new HashMap<>(); + int amountForChestSpace = Utils.getAmount(c.getInventory(), shop.getProduct()); + + if (amountForChestSpace == 0 && config.auto_calculate_item_amount) { + executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.OUT_OF_STOCK)); + return; + } + ItemStack product = new ItemStack(shop.getProduct()); Inventory inventory = executor.getInventory(); - for (int i = 0; i < 36; i++) { - ItemStack item = inventory.getItem(i); - if (item == null) { - slotFree.put(i, product.getMaxStackSize()); - } else { - if (item.isSimilar(product)) { - int amountInSlot = item.getAmount(); - int amountToFullStack = product.getMaxStackSize() - amountInSlot; - slotFree.put(i, amountToFullStack); - } - } + int freeSpace = Utils.getFreeSpaceForItem(inventory, product); + + int amountForPlayerInvSpace = (freeSpace >= product.getAmount() ? product.getAmount() : freeSpace); + + if (amountForPlayerInvSpace == 0 && config.auto_calculate_item_amount) { + executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_INVENTORY_SPACE)); + return; } - if (Utils.getMajorVersion() >= 9) { - ItemStack item = inventory.getItem(40); - if (item == null) { - slotFree.put(40, product.getMaxStackSize()); - } else { - if (item.isSimilar(product)) { - int amountInSlot = item.getAmount(); - int amountToFullStack = product.getMaxStackSize() - amountInSlot; - slotFree.put(40, amountToFullStack); - } - } - } + int newAmount = Math.min(Math.min(amountForMoney, amountForChestSpace), amountForPlayerInvSpace); + if (newAmount > shop.getProduct().getAmount()) newAmount = shop.getProduct().getAmount(); - int freeAmount = 0; - for (int value : slotFree.values()) { - freeAmount += value; - } + double newPrice = (shop.getBuyPrice() / shop.getProduct().getAmount()) * newAmount; - if (freeAmount >= product.getAmount()) { - plugin.debug(executor.getName() + " has enough inventory space (#" + shop.getID() + ")"); + if (freeSpace >= product.getAmount() || (config.auto_calculate_item_amount && freeSpace >= newAmount)) { + plugin.debug(executor.getName() + " has enough inventory space for " + freeSpace + " items (#" + shop.getID() + ")"); - EconomyResponse r = econ.withdrawPlayer(executor, shop.getBuyPrice()); - EconomyResponse r2 = (shop.getShopType() != ShopType.ADMIN) ? econ.depositPlayer(shop.getVendor(), shop.getBuyPrice()) : null; + ItemStack newProduct = new ItemStack(product); + newProduct.setAmount(newAmount); + + EconomyResponse r = econ.withdrawPlayer(executor, newPrice); + EconomyResponse r2 = (shop.getShopType() != ShopType.ADMIN) ? econ.depositPlayer(shop.getVendor(), newPrice) : null; if (r.transactionSuccess()) { if (r2 != null) { if (r2.transactionSuccess()) { - ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.BUY); + ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.BUY, newAmount, newPrice); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { - econ.depositPlayer(executor, shop.getBuyPrice()); - econ.withdrawPlayer(shop.getVendor(), shop.getBuyPrice()); + econ.depositPlayer(executor, newPrice); + econ.withdrawPlayer(shop.getVendor(), newPrice); plugin.debug("Buy event cancelled (#" + shop.getID() + ")"); return; } - addToInventory(inventory, product); - removeFromInventory(c.getInventory(), product); + addToInventory(inventory, newProduct); + removeFromInventory(c.getInventory(), newProduct); executor.updateInventory(); - executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.BUY_SUCCESS, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), - new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.BUY_PRICE, String.valueOf(shop.getBuyPrice())), + executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.BUY_SUCCESS, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(newAmount)), + new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.BUY_PRICE, String.valueOf(newPrice)), new LocalizedMessage.ReplacedRegex(Regex.VENDOR, shop.getVendor().getName()))); plugin.debug(executor.getName() + " successfully bought (#" + shop.getID() + ")"); if (shop.getVendor().isOnline()) { - shop.getVendor().getPlayer().sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SOMEONE_BOUGHT, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), - new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.BUY_PRICE, String.valueOf(shop.getBuyPrice())), + shop.getVendor().getPlayer().sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SOMEONE_BOUGHT, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(newAmount)), + new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.BUY_PRICE, String.valueOf(newPrice)), new LocalizedMessage.ReplacedRegex(Regex.PLAYER, executor.getName()))); } @@ -490,19 +501,19 @@ public class ShopInteractListener implements Listener { executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.ERROR_OCCURRED, new LocalizedMessage.ReplacedRegex(Regex.ERROR, r2.errorMessage))); } } else { - ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.BUY); + ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.BUY, newAmount, newPrice); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { - econ.depositPlayer(executor, shop.getBuyPrice()); + econ.depositPlayer(executor, newPrice); plugin.debug("Buy event cancelled (#" + shop.getID() + ")"); return; } - addToInventory(inventory, product); + addToInventory(inventory, newProduct); executor.updateInventory(); - executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.BUY_SUCESS_ADMIN, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), - new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.BUY_PRICE, String.valueOf(shop.getBuyPrice())))); + executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.BUY_SUCESS_ADMIN, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(newAmount)), + new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.BUY_PRICE, String.valueOf(newPrice)))); plugin.debug(executor.getName() + " successfully bought (#" + shop.getID() + ")"); } @@ -526,65 +537,77 @@ public class ShopInteractListener implements Listener { private void sell(Player executor, Shop shop) { plugin.debug(executor.getName() + " is selling (#" + shop.getID() + ")"); - if (econ.getBalance(shop.getVendor()) >= shop.getSellPrice() || shop.getShopType() == ShopType.ADMIN) { - plugin.debug("Vendor has enough money (#" + 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())); + + plugin.debug("Vendor has enough money for " + amountForMoney + " item(s) (#" + shop.getID() + ")"); + + if (amountForMoney == 0 && config.auto_calculate_item_amount) { + executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.VENDOR_NOT_ENOUGH_MONEY)); + return; + } Block block = shop.getLocation().getBlock(); Chest chest = (Chest) block.getState(); - HashMap slotFree = new HashMap<>(); + int amountForItemCount = Utils.getAmount(executor.getInventory(), shop.getProduct()); + + if (amountForItemCount == 0 && config.auto_calculate_item_amount) { + executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_ITEMS)); + return; + } + ItemStack product = new ItemStack(shop.getProduct()); Inventory inventory = chest.getInventory(); - for (int i = 0; i < inventory.getSize(); i++) { - ItemStack item = inventory.getItem(i); - if (item == null) { - slotFree.put(i, product.getMaxStackSize()); - } else { - if (item.isSimilar(product)) { - int amountInSlot = item.getAmount(); - int amountToFullStack = product.getMaxStackSize() - amountInSlot; - slotFree.put(i, amountToFullStack); - } - } + int freeSpace = Utils.getFreeSpaceForItem(inventory, product); + + int amountForChestSpace = (freeSpace >= product.getAmount() ? product.getAmount() : freeSpace); + + if (amountForChestSpace == 0 && config.auto_calculate_item_amount) { + executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CHEST_NOT_ENOUGH_INVENTORY_SPACE)); + return; } - int freeAmount = 0; - for (int value : slotFree.values()) { - freeAmount += value; - } + int newAmount = Math.min(Math.min(amountForMoney, amountForItemCount), amountForChestSpace); + if (newAmount > shop.getProduct().getAmount()) newAmount = shop.getProduct().getAmount(); - if (freeAmount >= product.getAmount()) { - plugin.debug("Chest has enough inventory space (#" + shop.getID() + ")"); + double newPrice = (shop.getSellPrice() / shop.getProduct().getAmount()) * newAmount; - EconomyResponse r = econ.depositPlayer(executor, shop.getSellPrice()); - EconomyResponse r2 = (shop.getShopType() != ShopType.ADMIN) ? econ.withdrawPlayer(shop.getVendor(), shop.getSellPrice()) : null; + if (freeSpace >= product.getAmount() || (config.auto_calculate_item_amount && freeSpace >= newAmount)) { + plugin.debug("Chest has enough inventory space for " + freeSpace + " items (#" + shop.getID() + ")"); + + ItemStack newProduct = new ItemStack(product); + newProduct.setAmount(newAmount); + + EconomyResponse r = econ.depositPlayer(executor, newPrice); + EconomyResponse r2 = (shop.getShopType() != ShopType.ADMIN) ? econ.withdrawPlayer(shop.getVendor(), newPrice) : null; if (r.transactionSuccess()) { if (r2 != null) { if (r2.transactionSuccess()) { - ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.SELL); + ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.SELL, newAmount, newPrice); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { - econ.withdrawPlayer(executor, shop.getBuyPrice()); - econ.depositPlayer(shop.getVendor(), shop.getBuyPrice()); + econ.withdrawPlayer(executor, newPrice); + econ.depositPlayer(shop.getVendor(), newPrice); plugin.debug("Sell event cancelled (#" + shop.getID() + ")"); return; } - addToInventory(inventory, product); - removeFromInventory(executor.getInventory(), product); + addToInventory(inventory, newProduct); + removeFromInventory(executor.getInventory(), newProduct); executor.updateInventory(); - executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SELL_SUCESS, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), - new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.SELL_PRICE, String.valueOf(shop.getSellPrice())), + executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SELL_SUCESS, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(newAmount)), + new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.SELL_PRICE, String.valueOf(newPrice)), new LocalizedMessage.ReplacedRegex(Regex.VENDOR, shop.getVendor().getName()))); plugin.debug(executor.getName() + " successfully sold (#" + shop.getID() + ")"); if (shop.getVendor().isOnline()) { - shop.getVendor().getPlayer().sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SOMEONE_SOLD, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), - new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.SELL_PRICE, String.valueOf(shop.getSellPrice())), + shop.getVendor().getPlayer().sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SOMEONE_SOLD, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(newAmount)), + new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.SELL_PRICE, String.valueOf(newPrice)), new LocalizedMessage.ReplacedRegex(Regex.PLAYER, executor.getName()))); } @@ -594,19 +617,19 @@ public class ShopInteractListener implements Listener { } } else { - ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.SELL); + ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.SELL, newAmount, newPrice); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { - econ.withdrawPlayer(executor, shop.getBuyPrice()); + econ.withdrawPlayer(executor, newPrice); plugin.debug("Sell event cancelled (#" + shop.getID() + ")"); return; } - removeFromInventory(executor.getInventory(), product); + removeFromInventory(executor.getInventory(), newProduct); executor.updateInventory(); - executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SELL_SUCESS_ADMIN, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), - new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.SELL_PRICE, String.valueOf(shop.getSellPrice())))); + executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SELL_SUCESS_ADMIN, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(newAmount)), + new LocalizedMessage.ReplacedRegex(Regex.ITEM_NAME, LanguageUtils.getItemName(product)), new LocalizedMessage.ReplacedRegex(Regex.SELL_PRICE, String.valueOf(newPrice)))); plugin.debug(executor.getName() + " successfully sold (#" + shop.getID() + ")"); } diff --git a/src/main/java/de/epiceric/shopchest/utils/Utils.java b/src/main/java/de/epiceric/shopchest/utils/Utils.java index b5abe67..0e1ac51 100644 --- a/src/main/java/de/epiceric/shopchest/utils/Utils.java +++ b/src/main/java/de/epiceric/shopchest/utils/Utils.java @@ -14,6 +14,7 @@ import javax.xml.bind.DatatypeConverter; import java.lang.reflect.InvocationTargetException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.HashMap; public class Utils { @@ -55,6 +56,65 @@ public class Utils { return amount; } + /** + * Get the amount of the given item, that fits in the given inventory + * + * @param inventory Inventory, where to search for free space + * @param itemStack Item, of which the amount that fits in the inventory should be returned + * @return Amount of the given item, that fits in the given inventory + */ + public static int getFreeSpaceForItem(Inventory inventory, ItemStack itemStack) { + HashMap slotFree = new HashMap<>(); + + if (inventory instanceof PlayerInventory) { + for (int i = 0; i < 36; i++) { + ItemStack item = inventory.getItem(i); + if (item == null) { + slotFree.put(i, itemStack.getMaxStackSize()); + } else { + if (item.isSimilar(itemStack)) { + int amountInSlot = item.getAmount(); + int amountToFullStack = itemStack.getMaxStackSize() - amountInSlot; + slotFree.put(i, amountToFullStack); + } + } + } + + if (getMajorVersion() >= 9) { + ItemStack item = inventory.getItem(40); + if (item == null) { + slotFree.put(40, itemStack.getMaxStackSize()); + } else { + if (item.isSimilar(itemStack)) { + int amountInSlot = item.getAmount(); + int amountToFullStack = itemStack.getMaxStackSize() - amountInSlot; + slotFree.put(40, amountToFullStack); + } + } + } + } else { + for (int i = 0; i < inventory.getSize(); i++) { + ItemStack item = inventory.getItem(i); + if (item == null) { + slotFree.put(i, itemStack.getMaxStackSize()); + } else { + if (item.isSimilar(itemStack)) { + int amountInSlot = item.getAmount(); + int amountToFullStack = itemStack.getMaxStackSize() - amountInSlot; + slotFree.put(i, amountToFullStack); + } + } + } + } + + int freeAmount = 0; + for (int value : slotFree.values()) { + freeAmount += value; + } + + return freeAmount; + } + /** * @param p Player whose item in his main hand should be returned * @return {@link ItemStack} in his main hand, or {@code null} if he doesn't hold one diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index cdc62c9..8c1d740 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -31,6 +31,16 @@ two-line-prices: false # A value of '1' equals to one block, and a value of '0.25' is equal to the height of one line. two-line-hologram-lift: 0.25 +# Set whether players should be allowed to sell their items, even if the amount they have, is +# lower than the amount, the shop owner has set for the given price, or if the inventory of the chest +# doesn't have enough space for all the items, but only for a few, or if the player only has enough money for +# a few items, but not for the amount, the shop owner has set. When set to true, players may also +# buy items from a shop, even if the amount of items in the chest is lower than the amount, the shop owner has +# set for the given price, or if they don't have enough space in the inventory for all of the items, but +# only for a few, or if the shop owner doesn't have enough money to buy all of the items, the player wants to sell. +# The price will be calculated correspondingly. (If it's not clear enough, please let me know) +auto-calculate-item-amount: false + # Set whether players should be allowed to sell/buy broken items allow-broken-items: false