package tc.oc.commons.bukkit.util;
import java.util.Collection;
import gnu.trove.set.TIntSet;
import gnu.trove.set.hash.TIntHashSet;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.material.MaterialData;
import org.bukkit.util.BlockVector;
public class MaterialUtils {
private MaterialUtils() {}
public static final int ENCODED_NULL_MATERIAL = -1;
/**
* Encode the given material and metadata to a single integer.
* The encoding is the same one Mojang uses in various places:
*
* typeId + metadata << 12
*/
public static int encodeMaterial(MaterialData material) {
return material == null ? ENCODED_NULL_MATERIAL
: encodeMaterial(material.getItemTypeId(), material.getData());
}
public static int encodeMaterial(int typeId, byte metadata) {
return typeId + (((int) metadata) << 12);
}
public static int encodeMaterial(Block block) {
return encodeMaterial(block.getTypeId(), block.getData());
}
public static int encodeMaterial(BlockState block) {
return encodeMaterial(block.getTypeId(), block.getRawData());
}
public static int encodeMaterial(Location location) {
return encodeMaterial(location.getBlock());
}
public static int encodeMaterial(World world, BlockVector pos) {
return encodeMaterial(world.getBlockAt(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()));
}
public static TIntSet encodeMaterialSet(Collection<?> materials) {
TIntSet set = new TIntHashSet(materials.size());
for(Object material : materials) {
if(material instanceof MaterialData) {
set.add(encodeMaterial((MaterialData) material));
}
}
return set;
}
public static int decodeTypeId(int encoded) {
return encoded & 0xfff;
}
public static byte decodeMetadata(int encoded) {
return (byte) (encoded >> 12);
}
public static Material decodeType(int encoded) {
return Material.getMaterial(decodeTypeId(encoded));
}
public static MaterialData decodeMaterial(int encoded) {
if(encoded == ENCODED_NULL_MATERIAL) return null;
Material material = decodeType(encoded);
if(material.getData() == MaterialData.class) {
return new MaterialData(material, decodeMetadata(encoded));
} else {
return material.getNewData(decodeMetadata(encoded));
}
}
}