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
This commit is contained in:
Eric 2016-08-16 15:06:26 +02:00
parent aa2051e9cc
commit 4bf5472e61
5 changed files with 205 additions and 90 deletions

View File

@ -103,6 +103,9 @@ public class Config {
*/ */
public boolean remove_shop_on_error; 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 **/ /** Amount the hologram should be lifted **/
public double two_line_hologram_lift; public double two_line_hologram_lift;
@ -276,6 +279,7 @@ public class Config {
database_type = Database.DatabaseType.valueOf(plugin.getConfig().getString("database.type")); database_type = Database.DatabaseType.valueOf(plugin.getConfig().getString("database.type"));
minimum_prices = (plugin.getConfig().getConfigurationSection("minimum-prices") == null) ? new HashSet<String>() : plugin.getConfig().getConfigurationSection("minimum-prices").getKeys(true); minimum_prices = (plugin.getConfig().getConfigurationSection("minimum-prices") == null) ? new HashSet<String>() : plugin.getConfig().getConfigurationSection("minimum-prices").getKeys(true);
allow_broken_items = plugin.getConfig().getBoolean("allow-broken-items"); 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<String>() : plugin.getConfig().getConfigurationSection("shop-limits.group").getKeys(true); shopLimits_group = (plugin.getConfig().getConfigurationSection("shop-limits.group") == null) ? new HashSet<String>() : plugin.getConfig().getConfigurationSection("shop-limits.group").getKeys(true);
shopLimits_player = (plugin.getConfig().getConfigurationSection("shop-limits.player") == null) ? new HashSet<String>() : plugin.getConfig().getConfigurationSection("shop-limits.player").getKeys(true); shopLimits_player = (plugin.getConfig().getConfigurationSection("shop-limits.player") == null) ? new HashSet<String>() : plugin.getConfig().getConfigurationSection("shop-limits.player").getKeys(true);
blacklist = (plugin.getConfig().getStringList("blacklist") == null) ? new ArrayList<String>() : plugin.getConfig().getStringList("blacklist"); blacklist = (plugin.getConfig().getStringList("blacklist") == null) ? new ArrayList<String>() : plugin.getConfig().getStringList("blacklist");

View File

@ -11,12 +11,16 @@ public class ShopBuySellEvent extends ShopEvent implements Cancellable {
private Player player; private Player player;
private Shop shop; private Shop shop;
private Type type; private Type type;
private int newAmount;
private double newPrice;
private boolean cancelled; 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.player = player;
this.shop = shop; this.shop = shop;
this.type = type; this.type = type;
this.newAmount = newAmount;
this.newPrice = newPrice;
} }
@Override @Override
@ -31,6 +35,20 @@ public class ShopBuySellEvent extends ShopEvent implements Cancellable {
return type; 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 @Override
public Player getPlayer() { public Player getPlayer() {
return player; return player;

View File

@ -1,6 +1,7 @@
package de.epiceric.shopchest.listeners; package de.epiceric.shopchest.listeners;
import de.epiceric.shopchest.ShopChest; import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.config.Regex; import de.epiceric.shopchest.config.Regex;
import de.epiceric.shopchest.event.ShopBuySellEvent; import de.epiceric.shopchest.event.ShopBuySellEvent;
import de.epiceric.shopchest.event.ShopCreateEvent; import de.epiceric.shopchest.event.ShopCreateEvent;
@ -48,6 +49,7 @@ public class ShopInteractListener implements Listener {
private Economy econ; private Economy econ;
private Database database; private Database database;
private ShopUtils shopUtils; private ShopUtils shopUtils;
private Config config;
public ShopInteractListener(ShopChest plugin) { public ShopInteractListener(ShopChest plugin) {
this.plugin = plugin; this.plugin = plugin;
@ -55,6 +57,7 @@ public class ShopInteractListener implements Listener {
this.econ = plugin.getEconomy(); this.econ = plugin.getEconomy();
this.database = plugin.getShopDatabase(); this.database = plugin.getShopDatabase();
this.shopUtils = plugin.getShopUtils(); this.shopUtils = plugin.getShopUtils();
this.config = plugin.getShopChestConfig();
} }
@EventHandler(priority = EventPriority.HIGH) @EventHandler(priority = EventPriority.HIGH)
@ -184,11 +187,15 @@ public class ShopInteractListener implements Listener {
Chest c = (Chest) b.getState(); Chest c = (Chest) b.getState();
if (Utils.getAmount(c.getInventory(), shop.getProduct()) >= shop.getProduct().getAmount()) { if (Utils.getAmount(c.getInventory(), shop.getProduct()) >= shop.getProduct().getAmount()) {
buy(p, shop); buy(p, shop);
} else {
if (config.auto_calculate_item_amount && Utils.getAmount(c.getInventory(), shop.getProduct()) > 0) {
buy(p, shop);
} else { } else {
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.OUT_OF_STOCK)); p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.OUT_OF_STOCK));
plugin.debug("Shop is out of stock"); plugin.debug("Shop is out of stock");
} }
} }
}
} else { } else {
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_BUY)); p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_BUY));
plugin.debug(p.getName() + " is not permitted to buy"); plugin.debug(p.getName() + " is not permitted to buy");
@ -221,10 +228,14 @@ public class ShopInteractListener implements Listener {
if (perm.has(p, "shopchest.sell")) { if (perm.has(p, "shopchest.sell")) {
if (Utils.getAmount(p.getInventory(), shop.getProduct()) >= shop.getProduct().getAmount()) { if (Utils.getAmount(p.getInventory(), shop.getProduct()) >= shop.getProduct().getAmount()) {
sell(p, shop); sell(p, shop);
} else {
if (config.auto_calculate_item_amount && Utils.getAmount(p.getInventory(), shop.getProduct()) > 0) {
sell(p, shop);
} else { } else {
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_ITEMS)); p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_ITEMS));
plugin.debug(p.getName() + " doesn't have enough items"); plugin.debug(p.getName() + " doesn't have enough items");
} }
}
} else { } else {
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_SELL)); p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_SELL));
plugin.debug(p.getName() + " is not permitted to sell"); plugin.debug(p.getName() + " is not permitted to sell");
@ -262,7 +273,7 @@ public class ShopInteractListener implements Listener {
plugin.debug(executor.getName() + " is creating new shop..."); plugin.debug(executor.getName() + " is creating new shop...");
int id = database.getNextFreeID(); 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); ShopCreateEvent event = new ShopCreateEvent(executor, Shop.createImaginaryShop(executor, product, location, buyPrice, sellPrice,shopType), creationPrice);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
@ -410,78 +421,78 @@ public class ShopInteractListener implements Listener {
*/ */
private void buy(Player executor, Shop shop) { private void buy(Player executor, Shop shop) {
plugin.debug(executor.getName() + " is buying (#" + shop.getID() + ")"); plugin.debug(executor.getName() + " is buying (#" + shop.getID() + ")");
if (econ.getBalance(executor) >= shop.getBuyPrice()) { if (econ.getBalance(executor) >= shop.getBuyPrice() || config.auto_calculate_item_amount) {
plugin.debug(executor.getName() + " has enough money (#" + shop.getID() + ")");
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(); Block b = shop.getLocation().getBlock();
Chest c = (Chest) b.getState(); Chest c = (Chest) b.getState();
HashMap<Integer, Integer> 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()); ItemStack product = new ItemStack(shop.getProduct());
Inventory inventory = executor.getInventory(); Inventory inventory = executor.getInventory();
for (int i = 0; i < 36; i++) { int freeSpace = Utils.getFreeSpaceForItem(inventory, product);
ItemStack item = inventory.getItem(i);
if (item == null) { int amountForPlayerInvSpace = (freeSpace >= product.getAmount() ? product.getAmount() : freeSpace);
slotFree.put(i, product.getMaxStackSize());
} else { if (amountForPlayerInvSpace == 0 && config.auto_calculate_item_amount) {
if (item.isSimilar(product)) { executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_INVENTORY_SPACE));
int amountInSlot = item.getAmount(); return;
int amountToFullStack = product.getMaxStackSize() - amountInSlot;
slotFree.put(i, amountToFullStack);
}
}
} }
if (Utils.getMajorVersion() >= 9) { int newAmount = Math.min(Math.min(amountForMoney, amountForChestSpace), amountForPlayerInvSpace);
ItemStack item = inventory.getItem(40); if (newAmount > shop.getProduct().getAmount()) newAmount = shop.getProduct().getAmount();
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 freeAmount = 0; double newPrice = (shop.getBuyPrice() / shop.getProduct().getAmount()) * newAmount;
for (int value : slotFree.values()) {
freeAmount += value;
}
if (freeAmount >= product.getAmount()) { if (freeSpace >= product.getAmount() || (config.auto_calculate_item_amount && freeSpace >= newAmount)) {
plugin.debug(executor.getName() + " has enough inventory space (#" + shop.getID() + ")"); plugin.debug(executor.getName() + " has enough inventory space for " + freeSpace + " items (#" + shop.getID() + ")");
EconomyResponse r = econ.withdrawPlayer(executor, shop.getBuyPrice()); ItemStack newProduct = new ItemStack(product);
EconomyResponse r2 = (shop.getShopType() != ShopType.ADMIN) ? econ.depositPlayer(shop.getVendor(), shop.getBuyPrice()) : null; 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 (r.transactionSuccess()) {
if (r2 != null) { if (r2 != null) {
if (r2.transactionSuccess()) { 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); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
econ.depositPlayer(executor, shop.getBuyPrice()); econ.depositPlayer(executor, newPrice);
econ.withdrawPlayer(shop.getVendor(), shop.getBuyPrice()); econ.withdrawPlayer(shop.getVendor(), newPrice);
plugin.debug("Buy event cancelled (#" + shop.getID() + ")"); plugin.debug("Buy event cancelled (#" + shop.getID() + ")");
return; return;
} }
addToInventory(inventory, product); addToInventory(inventory, newProduct);
removeFromInventory(c.getInventory(), product); removeFromInventory(c.getInventory(), newProduct);
executor.updateInventory(); executor.updateInventory();
executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.BUY_SUCCESS, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), 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(shop.getBuyPrice())), 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()))); new LocalizedMessage.ReplacedRegex(Regex.VENDOR, shop.getVendor().getName())));
plugin.debug(executor.getName() + " successfully bought (#" + shop.getID() + ")"); plugin.debug(executor.getName() + " successfully bought (#" + shop.getID() + ")");
if (shop.getVendor().isOnline()) { if (shop.getVendor().isOnline()) {
shop.getVendor().getPlayer().sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SOMEONE_BOUGHT, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), 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(shop.getBuyPrice())), 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()))); 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))); executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.ERROR_OCCURRED, new LocalizedMessage.ReplacedRegex(Regex.ERROR, r2.errorMessage)));
} }
} else { } 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); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
econ.depositPlayer(executor, shop.getBuyPrice()); econ.depositPlayer(executor, newPrice);
plugin.debug("Buy event cancelled (#" + shop.getID() + ")"); plugin.debug("Buy event cancelled (#" + shop.getID() + ")");
return; return;
} }
addToInventory(inventory, product); addToInventory(inventory, newProduct);
executor.updateInventory(); executor.updateInventory();
executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.BUY_SUCESS_ADMIN, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), 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(shop.getBuyPrice())))); 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() + ")"); plugin.debug(executor.getName() + " successfully bought (#" + shop.getID() + ")");
} }
@ -526,65 +537,77 @@ public class ShopInteractListener implements Listener {
private void sell(Player executor, Shop shop) { private void sell(Player executor, Shop shop) {
plugin.debug(executor.getName() + " is selling (#" + shop.getID() + ")"); plugin.debug(executor.getName() + " is selling (#" + shop.getID() + ")");
if (econ.getBalance(shop.getVendor()) >= shop.getSellPrice() || shop.getShopType() == ShopType.ADMIN) { if (econ.getBalance(shop.getVendor()) >= shop.getSellPrice() || shop.getShopType() == ShopType.ADMIN || config.auto_calculate_item_amount) {
plugin.debug("Vendor has enough money (#" + shop.getID() + ")"); 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(); Block block = shop.getLocation().getBlock();
Chest chest = (Chest) block.getState(); Chest chest = (Chest) block.getState();
HashMap<Integer, Integer> 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()); ItemStack product = new ItemStack(shop.getProduct());
Inventory inventory = chest.getInventory(); Inventory inventory = chest.getInventory();
for (int i = 0; i < inventory.getSize(); i++) { int freeSpace = Utils.getFreeSpaceForItem(inventory, product);
ItemStack item = inventory.getItem(i);
if (item == null) { int amountForChestSpace = (freeSpace >= product.getAmount() ? product.getAmount() : freeSpace);
slotFree.put(i, product.getMaxStackSize());
} else { if (amountForChestSpace == 0 && config.auto_calculate_item_amount) {
if (item.isSimilar(product)) { executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CHEST_NOT_ENOUGH_INVENTORY_SPACE));
int amountInSlot = item.getAmount(); return;
int amountToFullStack = product.getMaxStackSize() - amountInSlot;
slotFree.put(i, amountToFullStack);
}
}
} }
int freeAmount = 0; int newAmount = Math.min(Math.min(amountForMoney, amountForItemCount), amountForChestSpace);
for (int value : slotFree.values()) { if (newAmount > shop.getProduct().getAmount()) newAmount = shop.getProduct().getAmount();
freeAmount += value;
}
if (freeAmount >= product.getAmount()) { double newPrice = (shop.getSellPrice() / shop.getProduct().getAmount()) * newAmount;
plugin.debug("Chest has enough inventory space (#" + shop.getID() + ")");
EconomyResponse r = econ.depositPlayer(executor, shop.getSellPrice()); if (freeSpace >= product.getAmount() || (config.auto_calculate_item_amount && freeSpace >= newAmount)) {
EconomyResponse r2 = (shop.getShopType() != ShopType.ADMIN) ? econ.withdrawPlayer(shop.getVendor(), shop.getSellPrice()) : null; 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 (r.transactionSuccess()) {
if (r2 != null) { if (r2 != null) {
if (r2.transactionSuccess()) { 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); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
econ.withdrawPlayer(executor, shop.getBuyPrice()); econ.withdrawPlayer(executor, newPrice);
econ.depositPlayer(shop.getVendor(), shop.getBuyPrice()); econ.depositPlayer(shop.getVendor(), newPrice);
plugin.debug("Sell event cancelled (#" + shop.getID() + ")"); plugin.debug("Sell event cancelled (#" + shop.getID() + ")");
return; return;
} }
addToInventory(inventory, product); addToInventory(inventory, newProduct);
removeFromInventory(executor.getInventory(), product); removeFromInventory(executor.getInventory(), newProduct);
executor.updateInventory(); executor.updateInventory();
executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SELL_SUCESS, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), 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(shop.getSellPrice())), 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()))); new LocalizedMessage.ReplacedRegex(Regex.VENDOR, shop.getVendor().getName())));
plugin.debug(executor.getName() + " successfully sold (#" + shop.getID() + ")"); plugin.debug(executor.getName() + " successfully sold (#" + shop.getID() + ")");
if (shop.getVendor().isOnline()) { if (shop.getVendor().isOnline()) {
shop.getVendor().getPlayer().sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SOMEONE_SOLD, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), 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(shop.getSellPrice())), 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()))); new LocalizedMessage.ReplacedRegex(Regex.PLAYER, executor.getName())));
} }
@ -594,19 +617,19 @@ public class ShopInteractListener implements Listener {
} }
} else { } 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); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
econ.withdrawPlayer(executor, shop.getBuyPrice()); econ.withdrawPlayer(executor, newPrice);
plugin.debug("Sell event cancelled (#" + shop.getID() + ")"); plugin.debug("Sell event cancelled (#" + shop.getID() + ")");
return; return;
} }
removeFromInventory(executor.getInventory(), product); removeFromInventory(executor.getInventory(), newProduct);
executor.updateInventory(); executor.updateInventory();
executor.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.SELL_SUCESS_ADMIN, new LocalizedMessage.ReplacedRegex(Regex.AMOUNT, String.valueOf(product.getAmount())), 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(shop.getSellPrice())))); 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() + ")"); plugin.debug(executor.getName() + " successfully sold (#" + shop.getID() + ")");
} }

View File

@ -14,6 +14,7 @@ import javax.xml.bind.DatatypeConverter;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
public class Utils { public class Utils {
@ -55,6 +56,65 @@ public class Utils {
return amount; 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<Integer, Integer> 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 * @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 * @return {@link ItemStack} in his main hand, or {@code null} if he doesn't hold one

View File

@ -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. # 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 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 # Set whether players should be allowed to sell/buy broken items
allow-broken-items: false allow-broken-items: false