Java tutorial
/* * RealShopping Bukkit plugin for Minecraft * Copyright 2013 Jakub Fojt * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package com.github.kuben.realshopping; import com.github.kuben.realshopping.exceptions.RealShoppingException; import com.github.kuben.realshopping.listeners.RSPlayerListener; import com.github.kuben.realshopping.prompts.PromptMaster; import com.github.stengun.realshopping.Pager; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.lang.ArrayUtils; import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.Chest; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.material.MaterialData; public class Shop {//TODO add load/save interface public Shop(String name, String world, String owner) { super(); this.name = name; this.world = world; this.owner = owner; } /* * * Vars * */ private String name, world, owner;//Admin stores: owner = @admin private int buyFor = 0; /* * * Getters and Setters * */ public String getName() { return name; } public String getWorld() { return world; } public String getOwner() { return owner; } public int getBuyFor() { return buyFor; } public void setBuyFor(int buyFor) { this.buyFor = buyFor; } /* * * Entrance/Exit * */ public void addEntranceExit(Location en, Location ex) throws RealShoppingException { EEPair ep = new EEPair(en, ex); RealShopping.addEntranceExit(ep, this); } public boolean removeEntranceExit(Location en, Location ex) { return RealShopping.removeEntranceExit(this, en, ex); } public boolean removeEEPair(CommandSender player, int index) { boolean retval = false; EEPair[] pairs = RealShopping.getEEPairMap(this).keySet().toArray(new EEPair[0]); if (index >= pairs.length || index < 0) return false; retval = RealShopping.removeEntranceExit(this, pairs[index]); player.sendMessage("EEPair removed: " + pairs[index].toString()); return retval; } public int clearEntrancesExits() { return RealShopping.clearEntrancesExits(this); } public boolean hasEntrance(Location en) { return RealShopping.hasEntrance(this, en); } public boolean hasExit(Location ex) { return RealShopping.hasExit(this, ex); } public Location getFirstE() { return RealShopping.getRandomEntrance(this); } public Location getCorrEntrance(Location ex) { return RealShopping.getEntrance(this, ex); } public Location getCorrExit(Location en) { return RealShopping.getExit(this, en); } /* * * Chest functions * [0] is ID, [1] is data, [2] is amount(0 if full stack) */ private Map<Location, ArrayList<Integer[]>> chests = new HashMap<>(); public Map<Location, ArrayList<Integer[]>> getChests() { return chests; } public boolean addChest(Location l) { if (!chests.containsKey(l)) { chests.put(l, new ArrayList<Integer[]>()); if (Config.isAutoprotect()) { protectedChests.add(l); } return true; } else { return false; } } public boolean delChest(Location l) { if (chests.containsKey(l)) { chests.remove(l); } else { return false; } protectedChests.remove(l); return true; } public boolean isChest(Location l) { return chests.containsKey(l); } public int addChestItem(Location l, int[][] id) { int j = -1; if (chests.containsKey(l)) { j++; for (int[] i : id) { if (chests.get(l).size() < 27) { if (Material.getMaterial(i[0]) != null) { chests.get(l).add(ArrayUtils.toObject(i)); j++; } } } } return j; } public boolean setChestContents(Location l, Inventory i) { if (chests.containsKey(l)) { if (i != null) { chests.get(l).clear(); for (ItemStack iS : i.getContents()) { if (iS != null) { int am = iS.getAmount(); if (am == iS.getType().getMaxStackSize()) { am = 0; } chests.get(l).add(new Integer[] { iS.getTypeId(), (int) iS.getData().getData(), am }); } else { chests.get(l).add(new Integer[] { 0, 0, 0 }); } } } } return false; } public int delChestItem(Location l, int[][] id) { int j = -1; if (chests.containsKey(l)) { j++; for (int[] i : id) { boolean match = false; int k = 0; for (; k < chests.get(l).size(); k++) { if (chests.get(l).get(k)[0] == i[0] && chests.get(l).get(k)[1] == i[1]) { match = true; break; } } if (match) { chests.get(l).remove(k); j++; } } } return j; } public int clearChestItems(Location l) { int j = -1; if (chests.containsKey(l)) { j = chests.get(l).size(); chests.get(l).clear(); } return j; } /* * * Prices * Map stores pennies from 0.44 on */ private Map<Price, Integer[]> prices = new HashMap<>();//Price array [0] is price, [1] is min and [2] is maxprice public boolean hasPrices() { return !prices.isEmpty(); } public boolean hasSimilarPrice(Price p) { if (prices.containsKey(p)) { return true; } for (Price pr : prices.keySet()) { if (pr.similar(p)) return true; } return false; } /** * Tells me if this store have a price for an item (not considering its amount). * @param p Price object to check. * @return true if the price is present, false otherwise. */ public boolean hasPrice(Price p) { if (prices.containsKey(p)) { return true; } for (Price pr : prices.keySet()) { if (pr.similarData(p)) return true; } return false; } /** * Gets, if present, the cost for given item. * The returned price amount will be less or equal than given one, and if not present * this method will return 0. * @param p Price to check. * @return The correct price for the item, 0.0 if not present. */ public double getCostPerUnit(Price p) { Price found = new Price(p.getType()); found.setAmount(0); for (Price pr : prices.keySet()) { if (p.compatible(pr)) { if (found.getAmount() < pr.getAmount()) { found = pr; } } } Integer[] r = prices.get(found); if (r == null) return 0.0; double retval = ((double) r[0]) / found.getAmount(); return retval; } public Map<Price, Integer> getCosts() { Map<Price, Integer> temp = new HashMap<>(); for (Price p : prices.keySet().toArray(new Price[0])) { temp.put(p, prices.get(p)[0]); } return temp; } public Map<Price, Integer[]> getPricesMap() { return prices; } /** * Sets a price for an item. * @param p Price to set. * @param i Integer object with new price. * @return null if the item was not present, otherwise will set the price and return the old one. */ public Integer setCost(Price p, Integer i) { Integer retval = null; if (prices.containsKey(p)) { retval = prices.get(p)[0]; prices.remove(p); } prices.put(p, new Integer[] { i }); return retval; } public boolean removePrice(Price p) { return prices.remove(p) != null; } public Integer getMin(Price p) { if (prices.containsKey(p) && prices.get(p).length == 3) { return prices.get(p)[1]; } return null; } public Integer getMax(Price p) { if (prices.containsKey(p) && prices.get(p).length == 3) { return prices.get(p)[2]; } return null; } public boolean hasMinMax(Price p) { return (prices.containsKey(p) && prices.get(p).length == 3); } public boolean setMinMax(Price p, Integer min, Integer max) { if (prices.containsKey(p)) { prices.put(p, new Integer[] { (int) getCostPerUnit(p), min, max }); return true; } return false; } public void clearMinMax(Price p) { setCost(p, (int) getCostPerUnit(p)); } public void clearPrices() { prices.clear(); } public boolean clonePrices(String store) { if (store == null) { prices = getLowestPrices(); return true; } if (!RealShopping.shopExists(store)) return false; prices = new HashMap<>(RealShopping.getShop(store).prices); return true; } public void setPrices(Map<Price, Integer[]> prices) { this.prices = prices; } /* * * Sales * */ private Map<Price, Integer> sale = new HashMap<>(); public boolean hasSales() { return !sale.isEmpty(); } public boolean hasSimilarSale(Price p) { for (Price pri : sale.keySet()) { if (pri.similar(p)) return true; } return false; } public Integer hasSale(Price p) { for (Price salpri : sale.keySet()) { if ((salpri.isIsgeneric() && p.similarButHash(salpri)) || salpri.equals(p) || salpri.similarData(p)) { return sale.get(salpri); } } return null; } public void clearSales() { sale.clear(); } public Integer getFirstSale() { return (Integer) sale.values().toArray()[0]; } public Integer getSale(Price p) { Integer saleval = hasSale(p); if (saleval != null) { return saleval; } return 0; } public void addSale(Price p, int pcnt) { sale.put(p, pcnt); } public void setSale(Map<Price, Integer> sale) { this.sale = sale; } /* * * Statistics * */ private Set<Statistic> stats = new HashSet<>(); public Set<Statistic> getStats() { return stats; } public void addStat(Statistic stat) { if (stat.getAmount() > 0) { stats.add(stat); } } public void removeStat(Statistic stat) { stats.remove(stat); } /* * * Stolen (to claim), banned, and protected * */ private List<ItemStack> toClaim = new ArrayList<>(); private Set<String> banned = new HashSet<>(); private Set<Location> protectedChests = new HashSet<>(); /** * Gets the list of items that wait to be claimed. * @return List of ItemStack ready to be used. */ public List<ItemStack> getToClaim() { return toClaim; } /** * Checks if a shop has items to claim. * @return true if there are some, false otherwise. */ public boolean hasToClaim() { return !toClaim.isEmpty(); } /** * Removes all items that waits to be claimed. */ public void clearToClaim() { toClaim.clear(); } /** * Manually sets a list of items * @param list_of_to_claim The list of items that we want to be in the shop's claim list. */ public void setToClaim(List<ItemStack> list_of_to_claim) { this.toClaim = list_of_to_claim; } /** * Adds items to claim list. * @param item item(s) to add. */ public void addToClaim(ItemStack... item) { toClaim.addAll(Arrays.asList(item)); } /** * Retrieves the first item in the claim list, removing it. * Calling this method in a for statement is the best way to use it. * If the list is empty, this method will return null. * @return The first item in the claim list, null if there are no items. */ public ItemStack pullFirstToClaim() { if (!toClaim.isEmpty()) { ItemStack tempIs = toClaim.get(0); toClaim.remove(tempIs); return tempIs; } return null; } public Set<String> getBanned() { return banned; } public boolean isBanned(String p) { return banned.contains(p); } public void addBanned(String p) { banned.add(p); } public void removeBanned(String p) { banned.remove(p); } public boolean isProtectedChest(Location chest) { return protectedChests.contains(chest); } public boolean addProtectedChest(Location chest) { return protectedChests.add(chest); } public boolean removeProtectedChest(Location chest) { return protectedChests.remove(chest); } /* * Player timer threads for page flipping. */ private static Map<String, Pager> timers = new HashMap<>(); /** * Retrieves a pager of a player. * @param player Player with the pager we want to retrieve. * @return The correspondent pager, null if a player has no pager. */ public static Pager getPager(String player) { return timers.get(player); } /** * Safely cleans all pagers. */ public static void resetPagers() { for (String pl : timers.keySet()) { removePager(pl); } } /** * Safely deletes a player's pager. * If a pager is not present it will do nothing. * @param player Player who's pager is going to be removed. */ public static void removePager(String player) { Pager pg = timers.get(player); if (pg == null) { return; } pg.setStop(true); try { pg.join(5000); } catch (InterruptedException ex) { RealShopping.logsevere(ex.getStackTrace().toString()); } timers.remove(player); } /** * This method allows for safe pager add. If a pager is present it will be * stopped and replaced with the new pager. * * @param player Player to add pager to. */ public static void addPager(String player) { if (timers.containsKey(player)) { Pager pg = timers.get(player); pg.setStop(true); try { pg.join(5000); } catch (InterruptedException ex) { Logger.getLogger(Shop.class.getName()).log(Level.SEVERE, null, ex); } } Pager pager = new Pager(player); pager.start(); timers.put(player, pager); } // ------- UTILS /** * Exports all protected chests and their location to a string. * The string exported is ready to be read and parsed. * String format: * worldname,x,y,z * separated with ;. * @return a string with world and location of protected chest. */ public String exportProtectedToString() { // TODO convert chest export to YAML format. if (!protectedChests.isEmpty()) { String tempS = ""; for (Location tempL : protectedChests) { if (!chests.containsKey(tempL)) { tempS += ";" + tempL.getWorld().getName() + "," + (int) tempL.getX() + "," + (int) tempL.getY() + "," + (int) tempL.getZ(); } } return (tempS.length() > 0) ? tempS.substring(1) : ""; } else { return ""; } } /** * Export all stats to String. This method is used to export stats when * deactivating the plugin. * * @return All stats converted to string. */ public String exportStats() { //TODO convert stats export to YAML format. String s = ""; for (Statistic stat : stats) { s += ";" + stat.getTime() + ":" + stat.isBought() + ":" + stat.getItem().export(stat.getAmount()); } return s; } @Override public String toString() { return "Shop " + name + (owner.equals("@admin") ? "" : " owned by " + owner) + " Prices: " + prices.toString(); } private Map<Price, Integer[]> getLowestPrices() { Map<Price, Integer[]> tempMap = new HashMap<>(); for (Shop shop : RealShopping.getShops()) { if (!shop.getName().equals(name)) { Price[] keys2 = shop.getCosts().keySet().toArray(new Price[0]); for (Price p : keys2) { if (tempMap.containsKey(p)) { if (tempMap.get(p)[0] > shop.getCostPerUnit(p)) tempMap.put(p, new Integer[] { (int) shop.getCostPerUnit(p) }); else tempMap.put(p, new Integer[] { (int) shop.getCostPerUnit(p) }); } } } } return tempMap; } /* * * Static Methods * */ /** * Lists all Entrance - Exit pairs of a given shop. * The list is ordered with numbers, you can use these numbers for delete purposes. * @param sender Player who wrote the command. * @param page Page we want to see. * @param shop Shop wich we need to list the pairs. * @return */ public static boolean listEEPairs(CommandSender sender, int page, Shop shop) { Map<EEPair, Shop> pairmap = RealShopping.getEEPairMap(shop); if (pairmap.isEmpty()) return false; EEPair[] pairs = pairmap.keySet().toArray(new EEPair[0]); if ((page - 1) * 9 >= pairs.length) { sender.sendMessage(ChatColor.RED + LangPack.THEREARENTTHATMANYPAGES); return false; } for (int i = 9 * (page - 1); i < 9 * page; i++) { if (i >= pairs.length) break; EEPair ee = pairs[i]; sender.sendMessage( i + " -----------------\n" + ee.toString() + "\nFor shop " + ChatColor.GREEN + shop.getName()); } sender.sendMessage(" -----------------"); if (page * 9 < pairs.length) {//Not last sender.sendMessage(LangPack.MOREITEMSONPAGE + ChatColor.YELLOW + (page + 1)); } return true; } /** * Gets the price for a single item and its amount. * @param shop Shop where to bring the price. * @param ist Item we want to check price to. * @return The price for that item. If not present, the price will be 0.0 */ public static float sellPrice(Shop shop, ItemStack ist) { int payment = 0; if (ist != null) { Price itm = new Price(ist); if (shop.hasPrice(itm)) { int amount = ((RealShopping.isTool(ist.getType())) ? 1 : ist.getAmount()); itm.setAmount(amount); double cost = shop.getCostPerUnit(itm); if (cost > 0.0) { int pcnt; if (shop.hasSale(itm) != null) { pcnt = 100 - shop.getSale(itm); cost *= pcnt / 100f; } cost *= shop.getBuyFor() / 100f; payment = (int) (cost * (RealShopping.isTool(ist.getType()) ? (RealShopping.getMaxDur(ist.getType()) - ist.getDurability()) / RealShopping.getMaxDur(ist.getType()) : amount));// Durability is treated as Malus for PrintPrices. } } } return payment / 100f; } /** * Sells items to the store. * In order to work, this method must be called from a player that actually <i>is</i> * in a store. * @param p Player that is going to sell an item. * @param iS Item that's going to be sold. * @return true if the item is sold, false if not or if the player is not in a store. */ public static boolean sellToStore(Player p, ItemStack[] iS) { if (!Config.isEnableSelling() || !RealShopping.hasPInv(p) || !RealShopping.getPInv(p).getShop().hasPrices() || RealShopping.getPInv(p).getShop().getBuyFor() < 1) { return false; } boolean retval = false; RSPlayerInventory pinv = RealShopping.getPInv(p); Shop shop = pinv.getShop(); float payment = 0.0f; List<ItemStack> sold = new ArrayList<>(); List<ItemStack> returned = new ArrayList<>(); for (int i = 0; i < iS.length; i++) { ItemStack replacement = null; if (iS[i] != null && iS[i].getAmount() >= pinv.getAmount(iS[i])) { int exceed = iS[i].getAmount() - pinv.getAmount(iS[i]); replacement = new ItemStack(iS[i]); if (exceed > 0) { replacement.setAmount(exceed); } iS[i].setAmount(pinv.getAmount(iS[i])); } float sellp = sellPrice(shop, iS[i]); if (sellp > 0.0f) { payment += sellp; sold.add(iS[i]); } else replacement = iS[i]; if (replacement != null) returned.add(replacement); } if (!sold.isEmpty()) { String own = shop.getOwner(); if (!own.equals("@admin")) { if (RSEconomy.getBalance(own) >= payment) { RSEconomy.deposit(p.getName(), payment); RSEconomy.withdraw(own, payment);//If player owned store, withdraw from owner p.sendMessage(ChatColor.GREEN + LangPack.SOLD + sold.size() + LangPack.ITEMSFOR + payment + LangPack.UNIT); RealShopping.sendNotification(own, LangPack.YOURSTORE + shop.getName() + LangPack.BOUGHTSTUFFFOR + payment + LangPack.UNIT + LangPack.FROM + p.getName()); //Adding stats and claim items for owner for (ItemStack key : sold) { if (Config.isEnableAI()) { shop.addStat(new Statistic(new Price(key), key.getAmount(), false)); } shop.addToClaim(key); } } else { p.sendMessage(ChatColor.RED + LangPack.OWNER + own + LangPack.CANTAFFORDTOBUYITEMSFROMYOUFOR + payment + LangPack.UNIT); p.getInventory().addItem(sold.toArray(new ItemStack[0])); sold.clear(); } } else { RSEconomy.deposit(p.getName(), payment); RSEconomy.withdraw(own, payment); p.sendMessage(ChatColor.GREEN + LangPack.SOLD + ChatColor.DARK_GREEN + sold.size() + ChatColor.GREEN + LangPack.ITEMSFOR + ChatColor.DARK_GREEN + payment + ChatColor.GREEN + LangPack.UNIT); if (RealShopping.getPlayerSettings(own).getBoughtNotifications(shop, (int) (payment))) RealShopping.sendNotification(own, LangPack.YOURSTORE + shop.getName() + LangPack.BOUGHTSTUFFFOR + payment + LangPack.UNIT + LangPack.FROM + p.getName()); } for (ItemStack sold_item : sold) { pinv.removeItem(sold_item, sold_item.getAmount()); retval = true; } } // Return unsold items to the player and remove sold ones from pinv. p.getInventory().addItem(returned.toArray(new ItemStack[0])); return retval; } /** * Prints on screen the shop's PrintPrices. * Prices are divided by pages, every page is composed of 9 lines. With this * method you must choose the page you want to see. * @param sender Player who wrote the command. * @param page Requested page. * @param shop Shop where to bring the price list. * @return true if the command was executed without problems. False if the store has no PrintPrices. */ public static boolean PrintPrices(CommandSender sender, int page, Shop shop) {//In 0.50+ pages start from 1 if (shop.hasPrices()) { int maxitems = 6; //how many items we want to show Map<Price, Integer> tempMap = shop.getCosts(); if (!tempMap.isEmpty()) { Price[] keys = tempMap.keySet().toArray(new Price[0]); if ((page - 1) * maxitems < keys.length) {//If page exists if (shop.hasSales()) { sender.sendMessage(ChatColor.GREEN + LangPack.THEREISA + ChatColor.DARK_GREEN + shop.getFirstSale() + ChatColor.GREEN + LangPack.PCNTOFFSALEAT + ChatColor.DARK_GREEN + shop.getName()); } for (int i = maxitems * (page - 1); i < maxitems * page; i++) { if (i >= tempMap.size()) break; int cost = tempMap.get(keys[i]); if (shop.hasSale(keys[i]) != null) {//There is a sale on that item. int pcnt = 100 - shop.getSale(keys[i]); cost *= pcnt / 100f; } sender.sendMessage(keys[i].formattedString(cost / 100f, shop.hasSale(keys[i]))); } if (page * maxitems < keys.length) {//Not last sender.sendMessage(LangPack.MOREITEMSONPAGE + ChatColor.YELLOW + (page + 1)); } } else { sender.sendMessage(ChatColor.RED + LangPack.THEREARENTTHATMANYPAGES); } } else { sender.sendMessage(ChatColor.RED + LangPack.THEREARENOPRICESSETFORTHISSTORE); return false; } } else { sender.sendMessage(ChatColor.RED + LangPack.THEREARENOPRICESSETFORTHISSTORE); return false; } return true; } /** * Performs cart checkout and payment for purchased items. * @param player The player that is going to pay for purchased items. * @param invs All inventories a player have. * @return true if this command was executed correctly. */ public static boolean pay(Player player, Inventory[] invs) { if (RealShopping.hasPInv(player)) { RSPlayerInventory pinv = RealShopping.getPInv(player); Shop shop = pinv.getShop(); if (shop.hasPrices()) { int toPay = pinv.toPay(invs); if (toPay == 0) { return false; } if (RSEconomy.getBalance(player.getName()) < toPay / 100f) { player.sendMessage( ChatColor.RED + LangPack.YOUCANTAFFORDTOBUYTHINGSFOR + toPay / 100f + LangPack.UNIT); return true; } RSEconomy.withdraw(player.getName(), toPay / 100f); if (!shop.getOwner().equals("@admin")) { RSEconomy.deposit(shop.getOwner(), toPay / 100f);//If player owned store, pay player if (RealShopping.getPlayerSettings(player.getName()).getSoldNotifications(shop, toPay / 100))//And send a notification perhaps RealShopping.sendNotification(shop.getOwner(), player.getName() + LangPack.BOUGHTSTUFFFOR + toPay / 100f + LangPack.UNIT + LangPack.FROMYOURSTORE + shop.getName() + "."); } Map<Price, Integer> bought = pinv.getBoughtWait(invs); for (Price p : bought.keySet()) { pinv.addBought(p, bought.get(p)); } if (Config.isEnableAI()) { for (Price key : bought.keySet()) { shop.addStat(new Statistic(key, bought.get(key), true)); } } player.sendMessage(ChatColor.GREEN + LangPack.YOUBOUGHTSTUFFFOR + toPay / 100f + LangPack.UNIT); return true; } else { player.sendMessage(ChatColor.RED + LangPack.THEREARENOPRICESSETFORTHISSTORE); return true; } } else player.sendMessage(ChatColor.RED + LangPack.YOURENOTINSIDEASTORE); return false; } /** * Correctly exits a player from a store. * This command can be executed only if the player is on a tile marked for "store exit", * otherwise it will return false. * @param player Player that executed this command. * @param cmd True if this command was called from the command line and not from a Listener. * @return true when exit is correctly performed, false if a player can't exit. */ public static boolean exit(Player player, boolean cmd) { if (RealShopping.hasPInv(player)) { if (!PromptMaster.isConversing(player) && !RSPlayerListener.hasConversationListener(player)) { Shop tempShop = RealShopping.getPInv(player).getShop(); if (RealShopping.getPInv(player).hasPaid() || player.getGameMode() == GameMode.CREATIVE || player.getName().equals(tempShop.getOwner())) { Location l = player.getLocation().getBlock().getLocation().clone(); if (tempShop.hasExit(l)) { l = tempShop.getCorrEntrance(l); RealShopping.removePInv(player); removePager(player.getName()); l.setPitch(player.getLocation().getPitch()); l.setYaw(player.getLocation().getYaw()); player.teleport(l.add(0.5, 0, 0.5)); player.sendMessage( ChatColor.GREEN + LangPack.YOULEFT + ChatColor.DARK_GREEN + tempShop.getName()); return true; } else if (cmd) player.sendMessage(ChatColor.RED + LangPack.YOURENOTATTHEEXITOFASTORE); } else player.sendMessage(ChatColor.RED + LangPack.YOUHAVENTPAIDFORALLYOURARTICLES); } else { player.sendRawMessage(ChatColor.RED + LangPack.YOU_CANT_DO_THIS_WHILE_IN_A_CONVERSATION); player.sendRawMessage( LangPack.ALL_CONVERSATIONS_CAN_BE_ABORTED_WITH_ + ChatColor.DARK_PURPLE + "quit"); } } else player.sendMessage(ChatColor.RED + LangPack.YOURENOTINSIDEASTORE); return false; } /** * Brings the player into the store correctly. * This command succedes only when the player is ina tile marked as "store entrance", * otherwise it will return false. * @param player Player that executed this command. * @param cmd True if this command was called from the command line, false if not. * @return True when this command executed correctly, false if a player can't perform this action. */ public static boolean enter(Player player, boolean cmd) { if (!PromptMaster.isConversing(player) && !RSPlayerListener.hasConversationListener(player)) { Location l = player.getLocation().getBlock().getLocation().clone(); Shop tempShop = RealShopping.isEntranceTo(l); if (tempShop != null) {//Enter shop Location ex = tempShop.getCorrExit(l); if (!tempShop.isBanned(player.getName().toLowerCase())) { ex.setPitch(player.getLocation().getPitch()); ex.setYaw(player.getLocation().getYaw()); player.teleport(ex.add(0.5, 0, 0.5)); RealShopping.addPInv(new RSPlayerInventory(player, tempShop)); player.sendMessage( ChatColor.GREEN + LangPack.YOUENTERED + ChatColor.DARK_GREEN + tempShop.getName()); //Refill chests Location[] chestArr = tempShop.getChests().keySet().toArray(new Location[0]); for (int i = 0; i < chestArr.length; i++) { Block tempChest = player.getWorld().getBlockAt(chestArr[i]); if (tempChest.getType() != Material.CHEST) tempChest.setType(Material.CHEST); BlockState blockState = tempChest.getState(); if (blockState instanceof Chest) { Chest chest = (Chest) blockState; chest.getBlockInventory().clear(); ItemStack[] itemStack = new ItemStack[27]; int k = 0; for (Integer[] j : tempShop.getChests().get(chestArr[i])) { itemStack[k] = new MaterialData(j[0], j[1].byteValue()).toItemStack( (j[2] == 0) ? Material.getMaterial(j[0]).getMaxStackSize() : j[2]); k++; } chest.getBlockInventory().setContents(itemStack); } } addPager(player.getName()); return true; } else player.sendMessage( ChatColor.RED + LangPack.YOUAREBANNEDFROM + ChatColor.DARK_RED + tempShop.getName()); } else if (cmd) player.sendMessage(ChatColor.RED + LangPack.YOURENOTATTHEENTRANCEOFASTORE); } else { player.sendRawMessage(ChatColor.RED + LangPack.YOU_CANT_DO_THIS_WHILE_IN_A_CONVERSATION); player.sendRawMessage(LangPack.ALL_CONVERSATIONS_CAN_BE_ABORTED_WITH_ + ChatColor.DARK_PURPLE + "quit"); } return false; } }