ChestShop-3/com/Acrobot/ChestShop/Shop/Shop.java
Acrobot a49d51ce97 - Changed to the new, more robust event system
- Added partial transactions (You have 5 items, shop wants 10 - you can sell your items for half the price)
- Added a warning to the HTML generator
- Fixed Towny integration
- Fixed occasional ArrayOutOfBoundsExceptions
- Fixed an error when a shop couldn't be created because a sign (not shop sign) was on other side of the block
- Added SCL (SimpleChestLock) protection plugin to supported plugins
- Updated Metrics (and added a new asynch thread for startup)
- Removed Bukkit-1.0 workaround
- Fixed plugin.yml formatting
2012-02-16 19:09:37 +01:00

233 lines
9.1 KiB
Java

package com.Acrobot.ChestShop.Shop;
import com.Acrobot.ChestShop.ChestShop;
import com.Acrobot.ChestShop.Chests.ChestObject;
import com.Acrobot.ChestShop.Config.Config;
import com.Acrobot.ChestShop.Config.Language;
import com.Acrobot.ChestShop.Config.Property;
import com.Acrobot.ChestShop.Economy.Economy;
import com.Acrobot.ChestShop.Logging.Logging;
import com.Acrobot.ChestShop.Permission;
import com.Acrobot.ChestShop.Utils.uBlock;
import com.Acrobot.ChestShop.Utils.uInventory;
import com.Acrobot.ChestShop.Utils.uSign;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
/**
* @author Acrobot
*/
public class Shop {
private final short durability;
private final ChestObject chest;
public final ItemStack stock;
public int stockAmount;
public float buyPrice;
public float sellPrice;
public final String owner;
private final Sign sign;
public Shop(ChestObject chest, boolean buy, Sign sign, ItemStack... itemStacks) {
this.stock = itemStacks[0];
this.durability = stock.getDurability();
this.chest = chest;
this.buyPrice = (buy ? uSign.buyPrice(sign.getLine(2)) : -1);
this.sellPrice = (!buy ? uSign.sellPrice(sign.getLine(2)) : -1);
this.owner = sign.getLine(0);
this.stockAmount = uSign.itemAmount(sign.getLine(1));
this.sign = sign;
}
public void buy(Player player) {
if (chest == null && !isAdminShop()) {
player.sendMessage(Config.getLocal(Language.NO_CHEST_DETECTED));
return;
}
if (buyPrice == -1) {
player.sendMessage(Config.getLocal(Language.NO_BUYING_HERE));
return;
}
if (!Permission.has(player, Permission.BUY) && !Permission.has(player, Permission.BUY_ID + Integer.toString(stock.getTypeId()))) {
player.sendMessage(Config.getLocal(Language.NO_PERMISSION));
return;
}
String playerName = player.getName();
if (!Economy.hasEnough(playerName, buyPrice)) {
int items = calculateItemAmount(Economy.balance(playerName), true);
if (!Config.getBoolean(Property.ALLOW_PARTIAL_TRANSACTIONS) || items < 1) {
player.sendMessage(Config.getLocal(Language.NOT_ENOUGH_MONEY));
return;
} else {
buyPrice = (buyPrice / stockAmount) * items;
stockAmount = items;
}
}
if (!stockFitsPlayer(player)) {
player.sendMessage(Config.getLocal(Language.NOT_ENOUGH_SPACE_IN_INVENTORY));
return;
}
String materialName = stock.getType().name();
if (!isAdminShop() && !hasEnoughStock()) {
int items = stockAmount(stock, durability);
if (!Config.getBoolean(Property.ALLOW_PARTIAL_TRANSACTIONS) || items < 1) {
player.sendMessage(Config.getLocal(Language.NOT_ENOUGH_STOCK));
if (!Config.getBoolean(Property.SHOW_MESSAGE_OUT_OF_STOCK)) return;
sendMessageToOwner(Config.getLocal(Language.NOT_ENOUGH_STOCK_IN_YOUR_SHOP).replace("%material", materialName));
return;
} else {
buyPrice = (buyPrice / stockAmount) * items;
stockAmount = items;
}
}
String account = getOwnerAccount();
if (!account.isEmpty() && Economy.hasAccount(account)) {
if (!isAdminShop()) Economy.add(account, buyPrice);
else Economy.addServer(account, buyPrice);
}
Economy.subtract(playerName, buyPrice);
if (!isAdminShop()) chest.removeItem(stock, durability, stockAmount);
String formatedPrice = Economy.formatBalance(buyPrice);
if (Config.getBoolean(Property.SHOW_TRANSACTION_INFORMATION_CLIENT)) {
player.sendMessage(Config.getLocal(Language.YOU_BOUGHT_FROM_SHOP)
.replace("%amount", String.valueOf(stockAmount))
.replace("%item", materialName)
.replace("%owner", owner)
.replace("%price", formatedPrice));
}
uInventory.add(player.getInventory(), stock, stockAmount);
Logging.logTransaction(true, this, player);
player.updateInventory();
if (Config.getBoolean(Property.SHOW_TRANSACTION_INFORMATION_OWNER)) {
sendMessageToOwner(Config.getLocal(Language.SOMEBODY_BOUGHT_FROM_YOUR_SHOP)
.replace("%amount", String.valueOf(stockAmount))
.replace("%item", materialName)
.replace("%buyer", playerName)
.replace("%price", formatedPrice));
}
if (Config.getBoolean(Property.BLOCK_UPDATE)) uBlock.blockUpdate(sign.getBlock());
}
public void sell(Player player) {
if (chest == null && !isAdminShop()) {
player.sendMessage(Config.getLocal(Language.NO_CHEST_DETECTED));
return;
}
if (sellPrice == -1) {
player.sendMessage(Config.getLocal(Language.NO_SELLING_HERE));
return;
}
if (!Permission.has(player, Permission.SELL) && !Permission.has(player, Permission.SELL_ID + Integer.toString(stock.getTypeId()))) {
player.sendMessage(Config.getLocal(Language.NO_PERMISSION));
return;
}
String account = getOwnerAccount();
boolean accountExists = !account.isEmpty() && Economy.hasAccount(account);
if (accountExists && !Economy.hasEnough(account, sellPrice)) {
int items = calculateItemAmount(Economy.balance(account), false);
if (!Config.getBoolean(Property.ALLOW_PARTIAL_TRANSACTIONS) || items < 1) {
player.sendMessage(Config.getLocal(Language.NOT_ENOUGH_MONEY_SHOP));
return;
} else {
sellPrice = (sellPrice / stockAmount) * items;
stockAmount = items;
}
}
if (uInventory.amount(player.getInventory(), stock, durability) < stockAmount) {
int items = uInventory.amount(player.getInventory(), stock, durability);
if (!Config.getBoolean(Property.ALLOW_PARTIAL_TRANSACTIONS) || items < 1) {
player.sendMessage(Config.getLocal(Language.NOT_ENOUGH_ITEMS_TO_SELL));
return;
} else {
sellPrice = (sellPrice / stockAmount) * items;
stockAmount = items;
}
}
if (!isAdminShop() && !stockFitsChest(chest)) {
player.sendMessage(Config.getLocal(Language.NOT_ENOUGH_SPACE_IN_CHEST));
return;
}
if (accountExists) Economy.subtract(account, sellPrice);
if (!isAdminShop()) chest.addItem(stock, stockAmount);
if (!isAdminShop()) Economy.add(player.getName(), sellPrice);
else Economy.addServer(player.getName(), sellPrice);
String materialName = stock.getType().name();
String formatedBalance = Economy.formatBalance(sellPrice);
if (Config.getBoolean(Property.SHOW_TRANSACTION_INFORMATION_CLIENT)) {
player.sendMessage(Config.getLocal(Language.YOU_SOLD_TO_SHOP)
.replace("%amount", String.valueOf(stockAmount))
.replace("%item", materialName)
.replace("%buyer", owner)
.replace("%price", formatedBalance));
}
uInventory.remove(player.getInventory(), stock, stockAmount, durability);
Logging.logTransaction(false, this, player);
player.updateInventory();
if (Config.getBoolean(Property.SHOW_TRANSACTION_INFORMATION_OWNER)) {
sendMessageToOwner(Config.getLocal(Language.SOMEBODY_SOLD_TO_YOUR_SHOP)
.replace("%amount", String.valueOf(stockAmount))
.replace("%item", materialName)
.replace("%seller", player.getName())
.replace("%price", formatedBalance));
}
if (Config.getBoolean(Property.BLOCK_UPDATE)) uBlock.blockUpdate(sign.getBlock());
}
private String getOwnerAccount() {
return uSign.isAdminShop(owner) ? Config.getString(Property.SERVER_ECONOMY_ACCOUNT) : owner;
}
private boolean isAdminShop() {
return uSign.isAdminShop(owner);
}
private boolean hasEnoughStock() {
return chest.hasEnough(stock, stockAmount, durability);
}
private int stockAmount(ItemStack item, short durability){
return chest.amount(item, durability);
}
private boolean stockFitsPlayer(Player player) {
return uInventory.fits(player.getInventory(), stock, stockAmount, durability) <= 0;
}
private boolean stockFitsChest(ChestObject chest) {
return chest.fits(stock, stockAmount, durability);
}
private int calculateItemAmount(double money, boolean buy) {
return (int) Math.floor(money / ((buy ? buyPrice : sellPrice) / stockAmount));
}
private void sendMessageToOwner(String msg) {
if (!isAdminShop()) {
Player player = ChestShop.getBukkitServer().getPlayer(owner);
if (player != null) {
player.sendMessage(msg);
}
}
}
}