2011-05-22 04:01:43 +02:00
|
|
|
package de.diddiz.util;
|
|
|
|
|
|
2011-11-04 21:31:24 +01:00
|
|
|
import static de.diddiz.util.MaterialName.materialName;
|
2011-12-06 16:30:59 +01:00
|
|
|
import java.io.File;
|
2011-05-22 04:01:43 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.Comparator;
|
|
|
|
|
import java.util.HashSet;
|
2012-07-28 08:01:21 +01:00
|
|
|
import java.util.List;
|
2011-05-22 04:01:43 +02:00
|
|
|
import java.util.Set;
|
|
|
|
|
import org.bukkit.ChatColor;
|
2011-06-20 13:28:54 +02:00
|
|
|
import org.bukkit.Chunk;
|
|
|
|
|
import org.bukkit.Location;
|
2012-09-22 15:44:20 +05:00
|
|
|
import org.bukkit.Material;
|
2011-06-20 13:28:54 +02:00
|
|
|
import org.bukkit.World;
|
2012-07-28 08:01:21 +01:00
|
|
|
import org.bukkit.block.BlockFace;
|
2011-07-18 20:09:46 +02:00
|
|
|
import org.bukkit.block.BlockState;
|
2012-06-24 10:44:31 +10:00
|
|
|
import org.bukkit.block.DoubleChest;
|
2011-05-22 04:01:43 +02:00
|
|
|
import org.bukkit.entity.Entity;
|
|
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
|
import org.bukkit.entity.TNTPrimed;
|
|
|
|
|
import org.bukkit.inventory.Inventory;
|
2012-06-23 18:16:23 +10:00
|
|
|
import org.bukkit.inventory.InventoryHolder;
|
2011-05-22 04:01:43 +02:00
|
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
|
|
|
|
|
|
public class BukkitUtils
|
|
|
|
|
{
|
2011-10-19 02:08:57 +02:00
|
|
|
private static final Set<Set<Integer>> blockEquivalents;
|
2012-07-28 08:01:21 +01:00
|
|
|
private static final Set<Integer> relativeBreakable;
|
2012-08-20 06:57:16 +02:00
|
|
|
private static final Set<Integer> relativeTopBreakable;
|
2011-05-22 04:01:43 +02:00
|
|
|
|
|
|
|
|
static {
|
|
|
|
|
blockEquivalents = new HashSet<Set<Integer>>(7);
|
|
|
|
|
blockEquivalents.add(new HashSet<Integer>(Arrays.asList(2, 3, 60)));
|
|
|
|
|
blockEquivalents.add(new HashSet<Integer>(Arrays.asList(8, 9, 79)));
|
|
|
|
|
blockEquivalents.add(new HashSet<Integer>(Arrays.asList(10, 11)));
|
|
|
|
|
blockEquivalents.add(new HashSet<Integer>(Arrays.asList(61, 62)));
|
|
|
|
|
blockEquivalents.add(new HashSet<Integer>(Arrays.asList(73, 74)));
|
|
|
|
|
blockEquivalents.add(new HashSet<Integer>(Arrays.asList(75, 76)));
|
|
|
|
|
blockEquivalents.add(new HashSet<Integer>(Arrays.asList(93, 94)));
|
2012-09-22 15:44:20 +05:00
|
|
|
|
2012-07-28 08:01:21 +01:00
|
|
|
relativeBreakable = new HashSet<Integer>(2);
|
|
|
|
|
relativeBreakable.add(63); // Sign
|
|
|
|
|
relativeBreakable.add(68); // Sign
|
|
|
|
|
relativeBreakable.add(65); // Ladder
|
|
|
|
|
relativeBreakable.add(77); // Button
|
2012-09-22 15:44:20 +05:00
|
|
|
|
2012-08-20 06:57:16 +02:00
|
|
|
relativeTopBreakable = new HashSet<Integer>(19);
|
|
|
|
|
relativeTopBreakable.add(6); ////Vegetation start////
|
|
|
|
|
relativeTopBreakable.add(31); //
|
|
|
|
|
relativeTopBreakable.add(32); //
|
|
|
|
|
relativeTopBreakable.add(37); //
|
|
|
|
|
relativeTopBreakable.add(38); //
|
|
|
|
|
relativeTopBreakable.add(39); //
|
|
|
|
|
relativeTopBreakable.add(40); //
|
|
|
|
|
relativeTopBreakable.add(59); //
|
|
|
|
|
relativeTopBreakable.add(81); //
|
|
|
|
|
relativeTopBreakable.add(83); ////Vegetation end////
|
|
|
|
|
relativeTopBreakable.add(27); // Powered rail
|
|
|
|
|
relativeTopBreakable.add(28); // Detector rail
|
|
|
|
|
relativeTopBreakable.add(66); // Rails
|
|
|
|
|
relativeTopBreakable.add(55); // Redstone
|
|
|
|
|
relativeTopBreakable.add(70); // Stone pressure plate
|
|
|
|
|
relativeTopBreakable.add(72); // Wood pressure plate
|
|
|
|
|
relativeTopBreakable.add(78); // Snow
|
|
|
|
|
relativeTopBreakable.add(93); // Redstone repeater
|
|
|
|
|
relativeTopBreakable.add(94); // Redstone repeater
|
2012-07-28 08:01:21 +01:00
|
|
|
}
|
2012-09-22 15:44:20 +05:00
|
|
|
|
2012-07-28 08:01:21 +01:00
|
|
|
/**
|
|
|
|
|
* Returns a list of block locations around the block that are of the type specified by the integer list parameter
|
|
|
|
|
*
|
|
|
|
|
* @param block
|
|
|
|
|
* @param type
|
|
|
|
|
* @return List of block locations around the block that are of the type specified by the integer list parameter
|
|
|
|
|
*/
|
|
|
|
|
public static List<Location> getBlocksNearby(org.bukkit.block.Block block, Set<Integer> type) {
|
|
|
|
|
ArrayList<Location> blocks = new ArrayList<Location>();
|
2012-09-22 15:44:20 +05:00
|
|
|
if (type.contains(block.getRelative(BlockFace.EAST).getTypeId()))
|
2012-07-28 08:01:21 +01:00
|
|
|
blocks.add(block.getRelative(BlockFace.EAST).getLocation());
|
2012-09-22 15:44:20 +05:00
|
|
|
if (type.contains(block.getRelative(BlockFace.WEST).getTypeId()))
|
2012-07-28 08:01:21 +01:00
|
|
|
blocks.add(block.getRelative(BlockFace.WEST).getLocation());
|
2012-09-22 15:44:20 +05:00
|
|
|
if (type.contains(block.getRelative(BlockFace.NORTH).getTypeId()))
|
2012-07-28 08:01:21 +01:00
|
|
|
blocks.add(block.getRelative(BlockFace.NORTH).getLocation());
|
2012-09-22 15:44:20 +05:00
|
|
|
if (type.contains(block.getRelative(BlockFace.SOUTH).getTypeId()))
|
2012-07-28 08:01:21 +01:00
|
|
|
blocks.add(block.getRelative(BlockFace.SOUTH).getLocation());
|
2012-09-22 15:44:20 +05:00
|
|
|
if (type.contains(block.getRelative(BlockFace.UP).getTypeId()))
|
2012-07-28 08:01:21 +01:00
|
|
|
blocks.add(block.getRelative(BlockFace.UP).getLocation());
|
|
|
|
|
return blocks;
|
2011-05-22 04:01:43 +02:00
|
|
|
}
|
|
|
|
|
|
2012-06-24 10:44:31 +10:00
|
|
|
public static int getInventoryHolderType(InventoryHolder holder) {
|
2012-08-05 14:49:01 +10:00
|
|
|
if (holder instanceof DoubleChest) {
|
2012-06-24 10:44:31 +10:00
|
|
|
return ((DoubleChest)holder).getLocation().getBlock().getTypeId();
|
2012-08-05 14:49:01 +10:00
|
|
|
} else if (holder instanceof BlockState) {
|
|
|
|
|
return ((BlockState)holder).getTypeId();
|
2012-06-24 10:44:31 +10:00
|
|
|
} else {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Location getInventoryHolderLocation(InventoryHolder holder) {
|
2012-08-05 14:49:01 +10:00
|
|
|
if (holder instanceof DoubleChest) {
|
2012-06-24 10:44:31 +10:00
|
|
|
return ((DoubleChest)holder).getLocation();
|
2012-08-05 14:49:01 +10:00
|
|
|
} else if (holder instanceof BlockState) {
|
|
|
|
|
return ((BlockState)holder).getLocation();
|
2012-06-24 10:44:31 +10:00
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-22 04:01:43 +02:00
|
|
|
public static ItemStack[] compareInventories(ItemStack[] items1, ItemStack[] items2) {
|
|
|
|
|
final ItemStackComparator comperator = new ItemStackComparator();
|
|
|
|
|
final ArrayList<ItemStack> diff = new ArrayList<ItemStack>();
|
2011-06-01 14:13:08 +02:00
|
|
|
final int l1 = items1.length, l2 = items2.length;
|
2011-05-22 04:01:43 +02:00
|
|
|
int c1 = 0, c2 = 0;
|
2011-06-01 14:13:08 +02:00
|
|
|
while (c1 < l1 || c2 < l2) {
|
|
|
|
|
if (c1 >= l1) {
|
2011-05-22 04:01:43 +02:00
|
|
|
diff.add(items2[c2]);
|
|
|
|
|
c2++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2011-06-01 14:13:08 +02:00
|
|
|
if (c2 >= l2) {
|
2011-05-22 04:01:43 +02:00
|
|
|
items1[c1].setAmount(items1[c1].getAmount() * -1);
|
|
|
|
|
diff.add(items1[c1]);
|
|
|
|
|
c1++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
final int comp = comperator.compare(items1[c1], items2[c2]);
|
|
|
|
|
if (comp < 0) {
|
|
|
|
|
items1[c1].setAmount(items1[c1].getAmount() * -1);
|
|
|
|
|
diff.add(items1[c1]);
|
|
|
|
|
c1++;
|
|
|
|
|
} else if (comp > 0) {
|
|
|
|
|
diff.add(items2[c2]);
|
|
|
|
|
c2++;
|
|
|
|
|
} else {
|
2011-05-25 03:16:14 +02:00
|
|
|
final int amount = items2[c2].getAmount() - items1[c1].getAmount();
|
2011-05-22 04:01:43 +02:00
|
|
|
if (amount != 0) {
|
|
|
|
|
items1[c1].setAmount(amount);
|
|
|
|
|
diff.add(items1[c1]);
|
|
|
|
|
}
|
|
|
|
|
c1++;
|
|
|
|
|
c2++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return diff.toArray(new ItemStack[diff.size()]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static ItemStack[] compressInventory(ItemStack[] items) {
|
|
|
|
|
final ArrayList<ItemStack> compressed = new ArrayList<ItemStack>();
|
|
|
|
|
for (final ItemStack item : items)
|
|
|
|
|
if (item != null) {
|
|
|
|
|
final int type = item.getTypeId();
|
|
|
|
|
final byte data = rawData(item);
|
|
|
|
|
boolean found = false;
|
|
|
|
|
for (final ItemStack item2 : compressed)
|
|
|
|
|
if (type == item2.getTypeId() && data == rawData(item2)) {
|
|
|
|
|
item2.setAmount(item2.getAmount() + item.getAmount());
|
|
|
|
|
found = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!found)
|
|
|
|
|
compressed.add(new ItemStack(type, item.getAmount(), (short)0, data));
|
|
|
|
|
}
|
|
|
|
|
Collections.sort(compressed, new ItemStackComparator());
|
|
|
|
|
return compressed.toArray(new ItemStack[compressed.size()]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static boolean equalTypes(int type1, int type2) {
|
|
|
|
|
if (type1 == type2)
|
|
|
|
|
return true;
|
|
|
|
|
for (final Set<Integer> equivalent : blockEquivalents)
|
|
|
|
|
if (equivalent.contains(type1) && equivalent.contains(type2))
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-26 17:34:34 +02:00
|
|
|
public static String friendlyWorldname(String worldName) {
|
2011-12-06 16:30:59 +01:00
|
|
|
return new File(worldName).getName();
|
2011-05-26 17:34:34 +02:00
|
|
|
}
|
|
|
|
|
|
2011-05-22 04:01:43 +02:00
|
|
|
public static Set<Set<Integer>> getBlockEquivalents() {
|
|
|
|
|
return blockEquivalents;
|
|
|
|
|
}
|
2012-09-22 15:44:20 +05:00
|
|
|
|
2012-07-28 08:01:21 +01:00
|
|
|
public static Set<Integer> getRelativeBreakables() {
|
|
|
|
|
return relativeBreakable;
|
|
|
|
|
}
|
2012-09-22 15:44:20 +05:00
|
|
|
|
2012-08-20 06:57:16 +02:00
|
|
|
public static Set<Integer> getRelativeTopBreakabls() {
|
|
|
|
|
return relativeTopBreakable;
|
|
|
|
|
}
|
2011-05-22 04:01:43 +02:00
|
|
|
|
2011-06-21 22:36:52 +02:00
|
|
|
public static String entityName(Entity entity) {
|
2011-05-22 04:01:43 +02:00
|
|
|
if (entity instanceof Player)
|
|
|
|
|
return ((Player)entity).getName();
|
|
|
|
|
if (entity instanceof TNTPrimed)
|
|
|
|
|
return "TNT";
|
|
|
|
|
return entity.getClass().getSimpleName().substring(5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void giveTool(Player player, int type) {
|
|
|
|
|
final Inventory inv = player.getInventory();
|
|
|
|
|
if (inv.contains(type))
|
2012-02-08 19:58:19 +01:00
|
|
|
player.sendMessage(ChatColor.RED + "You have already a " + materialName(type));
|
2011-05-22 04:01:43 +02:00
|
|
|
else {
|
|
|
|
|
final int free = inv.firstEmpty();
|
|
|
|
|
if (free >= 0) {
|
2011-06-13 13:21:53 +02:00
|
|
|
if (player.getItemInHand() != null && player.getItemInHand().getTypeId() != 0)
|
|
|
|
|
inv.setItem(free, player.getItemInHand());
|
2011-05-22 04:01:43 +02:00
|
|
|
player.setItemInHand(new ItemStack(type, 1));
|
2011-06-21 22:36:52 +02:00
|
|
|
player.sendMessage(ChatColor.GREEN + "Here's your " + materialName(type));
|
2011-05-22 04:01:43 +02:00
|
|
|
} else
|
|
|
|
|
player.sendMessage(ChatColor.RED + "You have no empty slot in your inventory");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static byte rawData(ItemStack item) {
|
2011-08-10 14:02:25 +02:00
|
|
|
return item.getType() != null ? item.getData() != null ? item.getData().getData() : 0 : 0;
|
2011-05-22 04:01:43 +02:00
|
|
|
}
|
2011-05-25 13:17:21 +02:00
|
|
|
|
2011-06-20 13:28:54 +02:00
|
|
|
public static int saveSpawnHeight(Location loc) {
|
|
|
|
|
final World world = loc.getWorld();
|
|
|
|
|
final Chunk chunk = world.getChunkAt(loc);
|
|
|
|
|
if (!world.isChunkLoaded(chunk))
|
|
|
|
|
world.loadChunk(chunk);
|
|
|
|
|
final int x = loc.getBlockX(), z = loc.getBlockZ();
|
|
|
|
|
int y = loc.getBlockY();
|
|
|
|
|
boolean lower = world.getBlockTypeIdAt(x, y, z) == 0, upper = world.getBlockTypeIdAt(x, y + 1, z) == 0;
|
|
|
|
|
while ((!lower || !upper) && y != 127) {
|
|
|
|
|
lower = upper;
|
|
|
|
|
upper = world.getBlockTypeIdAt(x, ++y, z) == 0;
|
|
|
|
|
}
|
|
|
|
|
while (world.getBlockTypeIdAt(x, y - 1, z) == 0 && y != 0)
|
|
|
|
|
y--;
|
|
|
|
|
return y;
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-27 21:37:32 +02:00
|
|
|
public static int modifyContainer(BlockState b, ItemStack item) {
|
2012-03-03 23:42:20 +10:00
|
|
|
if (b instanceof InventoryHolder) {
|
|
|
|
|
final Inventory inv = ((InventoryHolder)b).getInventory();
|
2011-08-27 21:37:32 +02:00
|
|
|
if (item.getAmount() < 0) {
|
|
|
|
|
item.setAmount(-item.getAmount());
|
|
|
|
|
final ItemStack tmp = inv.removeItem(item).get(0);
|
|
|
|
|
return tmp != null ? tmp.getAmount() : 0;
|
|
|
|
|
} else if (item.getAmount() > 0) {
|
|
|
|
|
final ItemStack tmp = inv.addItem(item).get(0);
|
|
|
|
|
return tmp != null ? tmp.getAmount() : 0;
|
|
|
|
|
}
|
2011-07-18 20:09:46 +02:00
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-22 15:44:20 +05:00
|
|
|
public static boolean canFall(World world, int x, int y, int z) {
|
|
|
|
|
Material mat = world.getBlockAt(x, y, z).getType();
|
|
|
|
|
|
|
|
|
|
// Air
|
|
|
|
|
if (mat == Material.AIR) {
|
|
|
|
|
return true;
|
|
|
|
|
} else if (mat == Material.WATER || mat == Material.STATIONARY_WATER || mat == Material.LAVA || mat == Material.STATIONARY_LAVA) { // Fluids
|
|
|
|
|
return true;
|
|
|
|
|
} else if (mat == Material.SIGN || mat == Material.FIRE) { // Misc.
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-01 14:13:08 +02:00
|
|
|
public static class ItemStackComparator implements Comparator<ItemStack>
|
2011-05-25 13:17:21 +02:00
|
|
|
{
|
|
|
|
|
@Override
|
|
|
|
|
public int compare(ItemStack a, ItemStack b) {
|
|
|
|
|
final int aType = a.getTypeId(), bType = b.getTypeId();
|
|
|
|
|
if (aType < bType)
|
|
|
|
|
return -1;
|
|
|
|
|
if (aType > bType)
|
|
|
|
|
return 1;
|
|
|
|
|
final byte aData = rawData(a), bData = rawData(b);
|
|
|
|
|
if (aData < bData)
|
|
|
|
|
return -1;
|
|
|
|
|
if (aData > bData)
|
|
|
|
|
return 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-05-22 04:01:43 +02:00
|
|
|
}
|