package io.github.lucaseasedup.logit.util; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; public final class BlockUtils { private BlockUtils() { } public static Block getNearestBlockBelow(Location location) { if (location == null) throw new IllegalArgumentException(); World world = location.getWorld(); int x = location.getBlockX(); int y = location.getBlockY(); int z = location.getBlockZ(); Block block; while ((block = world.getBlockAt(x, y, z)).isEmpty()) { y--; if (y < 0) { return null; } } return block; } public static boolean isMaterialSafe(Material material) { if (material == null) throw new IllegalArgumentException(); return material != Material.PORTAL && material != Material.LAVA && material != Material.WATER && material != Material.AIR && material != Material.STONE_PLATE && material != Material.WOOD_PLATE && material != Material.CACTUS && material != Material.FIRE && material != Material.GOLD_PLATE && material != Material.IRON_PLATE && material != Material.TRIPWIRE; } public static boolean isBlockAdjacent( Block block, BlockFace face, Material... toMaterials ) { if (block == null || face == null || toMaterials == null) throw new IllegalArgumentException(); block = block.getRelative(face); for (Material toMaterial : toMaterials) { if (block.getType() != toMaterial) { return false; } block = block.getRelative(face); } return true; } /** * Searches for the nearest safe location to stand at. * * <p>{@code block} is considered safe to stand on if * {@code BlockUtils.isMaterialSafe(block.getType()) == true}. * * @param origin the block around which search will start. * @param maxRadius maximum search radius. * * @return the nearest safe location for a player to stand at, * or {@code null} if no "safe space" was found. * * @author Njol * @modifiedby LucasEU */ public static Location getNearestSafeSpace(Location origin, int maxRadius) { if (origin == null) throw new IllegalArgumentException(); BlockFace[] faces = {BlockFace.UP, BlockFace.NORTH, BlockFace.EAST}; BlockFace[][] orths = { {BlockFace.NORTH, BlockFace.EAST}, {BlockFace.UP, BlockFace.EAST}, {BlockFace.NORTH, BlockFace.UP} }; for (int r = 0; r <= maxRadius; r++) { for (int i = 0; i < 6; i++) { BlockFace face = faces[i % 3]; BlockFace[] orth = orths[i % 3]; if (i >= 3) { face = face.getOppositeFace(); } Block referenceBlock = origin.getBlock().getRelative(face, r); for (int x = -r; x <= r; x++) { for (int y = -r; y <= r; y++) { Block block = referenceBlock .getRelative(orth[0], x) .getRelative(orth[1], y); if (isMaterialSafe(block.getType())) { if (isBlockAdjacent(block, BlockFace.UP, Material.AIR, Material.AIR)) { return block.getLocation().add(0.5, 1.0, 0.5); } } } } } } return null; } }