public boolean marketBottom(CommandSender sender) { // gather the list of commodities List<Commodities> commodities = plugin.getDatabase().find(Commodities.class).findList(); // sort 'em and return only the top 10 List<Commodities> top10 = plugin .getDatabase() .filter(Commodities.class) .sort("value asc") .maxRows(10) .filter(commodities); // calculate elasticity List<Integer> elasticities = new LinkedList<Integer>(); for (int index = 0; index < top10.size(); index++) { Commodities c = top10.get(index); double value = c.getValue(); double changeRate = c.getChangeRate(); double minValue = c.getMinValue(); if (value < minValue) { double newValue = Math.abs(value - minValue); double elasticity = (newValue / changeRate); int el = (int) Math.round(elasticity); elasticities.add(index, el); c.setValue(minValue); } else { elasticities.add(index, 0); } } // Send them to the player for (int x = 0; x < top10.size(); x++) { int rank = x + 1; sender.sendMessage( ChatColor.GREEN + String.valueOf(rank) + ". " + ChatColor.WHITE + top10.get(x).getName() + " " + ChatColor.GRAY + top10.get(x).getValue() + " " + ChatColor.DARK_GREEN + elasticities.get(x)); } return true; }
/** * Determine the cost of a given number of an item and calculate a new value for the item * accordingly. * * @param oper 1 for buying, 0 for selling. * @param commodity the commodity in question * @param amount the desired amount of the item in question * @return the total cost and the calculated new value as an Invoice */ public Invoice generateInvoice(int oper, Commodities commodity, int amount) { // get the initial value of the item, 0 for not found Invoice inv = new Invoice(0.0, 0.0); inv.value = commodity.getValue(); // get the spread so we can do one initial decrement of the value if we are selling BigDecimal spread = BigDecimal.valueOf(commodity.getSpread()); // determine the total cost inv.total = 0.0; for (int x = 1; x <= amount; x++) { BigDecimal minValue = BigDecimal.valueOf(commodity.getMinValue()); BigDecimal maxValue = BigDecimal.valueOf(commodity.getMaxValue()); BigDecimal changeRate = BigDecimal.valueOf(commodity.getChangeRate()); // work the spread on the first one. if ((oper == 0) && (x == 1)) { inv.subtractValue(spread.doubleValue()); } else if ((oper == 0) && (x > 1)) { // otherwise, do the usual decriment. inv.subtractValue(changeRate.doubleValue()); } // check the current value if (inv.getValue() >= minValue.doubleValue()) { // current value is @ or above minValue // be sure value is not above maxValue if (inv.getValue() < maxValue.doubleValue()) { // current value is "just right" inv.addTotal(inv.getValue()); // add current value to total } else { // current value is above the max inv.addTotal(maxValue.doubleValue()); // add maxValue to total } } else { // current value is below the minimum inv.addTotal(minValue.doubleValue()); // add the minimum to total if ((oper == 0) && (x == 1)) { inv.subtractTotal( spread .doubleValue()); // subtract the spread if we're selling and this is the first run } } // Change our stored value for the item // we don't care about min/maxValue here because we don't want the value to 'bounce' off of // them. if (oper == 1) { inv.addValue(changeRate.doubleValue()); } } return inv; }
public BigDecimal price(String item) { // retrieve the commodity in question Commodities commodity = plugin.getDatabase().find(Commodities.class).where().ieq("name", item).findUnique(); if (commodity == null) return null; double price = commodity.getValue(); double minValue = commodity.getMinValue(); double maxValue = commodity.getMaxValue(); if (price > maxValue) return BigDecimal.valueOf(maxValue).setScale(2, RoundingMode.HALF_UP); if (price < minValue) return BigDecimal.valueOf(minValue).setScale(2, RoundingMode.HALF_UP); return BigDecimal.valueOf(price).setScale(2, RoundingMode.HALF_UP); }
/** * Sell a specified amount of an item for the player. * * @param player The player on behalf of which these actions will be carried out. * @param item The desired item in the form of the item name. * @param amount The desired amount of the item to sell. * @return true on success, false on failure. */ public boolean sell(Player player, String item, int amount) { // Be sure we have a positive amount if (amount < 1) { player.sendMessage(ChatColor.RED + "Invalid amount."); player.sendMessage("No negative numbers or zero, please."); return false; } // retrieve the commodity in question Commodities commodity = plugin.getDatabase().find(Commodities.class).where().ieq("name", item).findUnique(); if (commodity == null) { player.sendMessage(ChatColor.RED + "Not allowed to buy that item."); player.sendMessage("Be sure you typed the correct name"); return false; } // determine what it will pay Invoice invoice = generateInvoice(0, commodity, amount); // If the player has enough of the item, perform the transaction. int id = commodity.getNumber(); Byte byteData = Byte.valueOf(String.valueOf(commodity.getData())); ItemStack its = new ItemStack(id, amount, (short) 0, byteData); if (player.getInventory().contains(id)) { // Figure out how much is left over int left = getAmountInInventory(player, its) - amount; if (left < 0) { // this indicates the correct id, but the wrong bytedata value // give nice output even if they gave a bad name. player.sendMessage(ChatColor.RED + "You don't have enough " + item); player.sendMessage( ChatColor.GREEN + "In Inventory: " + ChatColor.WHITE + getAmountInInventory(player, its)); player.sendMessage(ChatColor.GREEN + "Attempted Amount: " + ChatColor.WHITE + amount); return false; } // Take out all of the item int x = 0; for (@SuppressWarnings("unused") ItemStack stack : player .getInventory() .getContents()) { // we do it this way incase a user has an expanded inventory via // another plugin ItemStack slot = player.getInventory().getItem(x); if (slot != null) { Byte slotData = Byte.valueOf("0"); try { slotData = slot.getData().getData(); } catch (NullPointerException e) { } if ((slot.getTypeId() == id) && (slotData.compareTo(byteData) == 0)) { player.getInventory().clear(x); } } x++; } // put back what was left over if (left > 0) { ItemStack itsLeft = its; itsLeft.setAmount(left); player.getInventory().addItem(itsLeft); } // record the change in value commodity.setValue(invoice.getValue()); plugin.getDatabase().save(commodity); // use BigDecimal to format value for output double v = commodity.getValue(); double max = commodity.getMaxValue(); double min = commodity.getMinValue(); BigDecimal value; if (v < max && v > min) { value = BigDecimal.valueOf(v).setScale(2, RoundingMode.HALF_UP); } else if (v <= min) { value = BigDecimal.valueOf(min).setScale(2, RoundingMode.HALF_UP); } else { value = BigDecimal.valueOf(max).setScale(2, RoundingMode.HALF_UP); } BigDecimal spread = BigDecimal.valueOf(commodity.getSpread()); // give some nice output BigDecimal sale = BigDecimal.valueOf((invoice.getTotal() + spread.doubleValue())) .setScale(2, RoundingMode.HALF_UP); player.sendMessage(ChatColor.GREEN + "--------------------------------"); player.sendMessage( ChatColor.GREEN + "Old Balance: " + ChatColor.WHITE + BigDecimal.valueOf(economy.getBalance(player.getName())) .setScale(2, RoundingMode.HALF_UP)); // deposit the money economy.depositPlayer(player.getName(), invoice.getTotal()); player.sendMessage(ChatColor.GREEN + "Sale: " + ChatColor.WHITE + sale); player.sendMessage(ChatColor.GREEN + "Selling Fee: " + ChatColor.WHITE + spread); player.sendMessage(ChatColor.GREEN + "--------------------------------"); player.sendMessage( ChatColor.GREEN + "Net Gain: " + ChatColor.WHITE + BigDecimal.valueOf(invoice.getTotal()).setScale(2, RoundingMode.HALF_UP)); player.sendMessage( ChatColor.GREEN + "New Balance: " + ChatColor.WHITE + BigDecimal.valueOf(economy.getBalance(player.getName())) .setScale(2, RoundingMode.HALF_UP)); player.sendMessage(ChatColor.GREEN + "--------------------------------"); player.sendMessage( ChatColor.GRAY + item + ChatColor.GREEN + " New Price: " + ChatColor.WHITE + value); return true; } else { // give nice output even if they gave a bad number. player.sendMessage(ChatColor.RED + "You don't have enough " + item); player.sendMessage( ChatColor.GREEN + "In Inventory: " + ChatColor.WHITE + getAmountInInventory(player, its)); player.sendMessage(ChatColor.GREEN + "Attempted Amount: " + ChatColor.WHITE + amount); return false; } }
/** * Buy a specified amount of an item for the player. * * @param player The player on behalf of which these actions will be carried out. * @param item The desired item in the form of the item name. * @param amount The desired amount of the item to purchase. * @return true on success, false on failure. */ public boolean buy(Player player, String item, int amount) { // Be sure we have a positive amount if (amount < 1) { player.sendMessage(ChatColor.RED + "Invalid amount."); player.sendMessage("No negative numbers or zero, please."); return false; } // retrieve the commodity in question Commodities commodity = plugin.getDatabase().find(Commodities.class).where().ieq("name", item).findUnique(); // check that we found something if (commodity == null) { player.sendMessage(ChatColor.RED + "Not allowed to buy that item."); player.sendMessage("Be sure you typed the correct name"); return false; } // determine what it will cost Invoice invoice = generateInvoice(1, commodity, amount); // check the player's wallet if (economy.has(player.getName(), invoice.getTotal())) { // give 'em the items and drop any extra Byte byteData = Byte.valueOf(String.valueOf(commodity.getData())); int id = commodity.getNumber(); HashMap<Integer, ItemStack> overflow = player.getInventory().addItem(new ItemStack(id, amount, (short) 0, byteData)); for (int a : overflow.keySet()) { player.getWorld().dropItem(player.getLocation(), overflow.get(a)); } // save the new value commodity.setValue(invoice.getValue()); getDatabase().save(commodity); // use BigDecimal to format value for output double v = commodity.getValue(); double max = commodity.getMaxValue(); double min = commodity.getMinValue(); BigDecimal value; if (v < max && v > min) { value = BigDecimal.valueOf(v).setScale(2, RoundingMode.HALF_UP); } else if (v <= min) { value = BigDecimal.valueOf(min).setScale(2, RoundingMode.HALF_UP); } else { value = BigDecimal.valueOf(max).setScale(2, RoundingMode.HALF_UP); } // Give some nice output. player.sendMessage(ChatColor.GREEN + "--------------------------------"); player.sendMessage( ChatColor.GREEN + "Old Balance: " + ChatColor.WHITE + BigDecimal.valueOf(economy.getBalance(player.getName())) .setScale(2, RoundingMode.HALF_UP)); // Subtract the invoice (this is an efficient place to do this) economy.withdrawPlayer(player.getName(), invoice.getTotal()); player.sendMessage( ChatColor.GREEN + "Cost: " + ChatColor.WHITE + BigDecimal.valueOf(invoice.getTotal()).setScale(2, RoundingMode.HALF_UP)); player.sendMessage( ChatColor.GREEN + "New Balance: " + ChatColor.WHITE + BigDecimal.valueOf(economy.getBalance(player.getName())) .setScale(2, RoundingMode.HALF_UP)); player.sendMessage(ChatColor.GREEN + "--------------------------------"); player.sendMessage( ChatColor.GRAY + item + ChatColor.GREEN + " New Price: " + ChatColor.WHITE + value); return true; } else { // Otherwise, give nice output anyway ;) // The idea here is to show how much more money is needed. BigDecimal difference = BigDecimal.valueOf(economy.getBalance(player.getName()) - invoice.getTotal()) .setScale(2, RoundingMode.HALF_UP); player.sendMessage(ChatColor.RED + "You don't have enough money"); player.sendMessage( ChatColor.GREEN + "Balance: " + ChatColor.WHITE + BigDecimal.valueOf(economy.getBalance(player.getName())) .setScale(2, RoundingMode.HALF_UP)); player.sendMessage( ChatColor.GREEN + "Cost: " + ChatColor.WHITE + BigDecimal.valueOf(invoice.getTotal()).setScale(2, RoundingMode.HALF_UP)); player.sendMessage(ChatColor.GREEN + "Difference: " + ChatColor.RED + difference); return true; } }