Skip to content

Instantly share code, notes, and snippets.

@NanoAi
Created May 30, 2020 02:54
Show Gist options
  • Save NanoAi/a9e92743e6215723f558c097f1c1b18f to your computer and use it in GitHub Desktop.
Save NanoAi/a9e92743e6215723f558c097f1c1b18f to your computer and use it in GitHub Desktop.
package red.mirai.lunaticmode.modules;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.FallingBlock;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import red.mirai.lunaticmode.LunaticMode;
import java.util.concurrent.ConcurrentLinkedQueue;
public class FallingTrees implements Listener {
ConcurrentLinkedQueue<Block> blockBreakQuery = new ConcurrentLinkedQueue<>();
private boolean checkBlock( Block block, Location source ) {
Material type = block.getType();
if ( type.isAir() ) return false;
boolean isLeaves = ( type.toString().endsWith( "_LEAVES" ) );
boolean isLog = ( type.toString().endsWith( "_LOG" ) );
boolean xInRange = ( Math.abs( source.getBlockX() - block.getX() ) < 9 );
boolean yInRange = ( Math.abs( source.getBlockY() - block.getY() ) < 30 );
boolean zInRange = ( Math.abs( source.getBlockZ() - block.getZ() ) < 9 );
if ( !( xInRange && yInRange && zInRange ) ) return false;
if ( isLog && ( block.getX() == source.getBlockX() && block.getY() == source.getBlockY() ) ) {
return false;
}
return ( isLog || isLeaves );
}
private void syncedBreak( Block block, ItemStack tool ) {
new BukkitRunnable() {
@Override
public void run() {
if ( block != null ) {
if ( tool == null ) {
block.breakNaturally();
} else {
block.breakNaturally( tool );
}
}
}
}.runTask( LunaticMode.plugin );
}
private void breakTree( Block source, ItemStack tool ) {
Location sourceLocation = source.getLocation();
for ( BlockFace face : BlockFace.values() ) {
Block blockAtFace = source.getRelative( face );
if ( checkBlock( blockAtFace, sourceLocation ) ) {
blockBreakQuery.add( blockAtFace );
}
}
new BukkitRunnable() {
@Override
public void run() {
if ( blockBreakQuery.size() == 0 ) {
cancel();
}
Block polledBlock = blockBreakQuery.poll();
if ( polledBlock == null ) return;
if ( checkBlock( polledBlock, sourceLocation ) ) {
syncedBreak( polledBlock, tool );
}
for ( BlockFace face : BlockFace.values() ) {
Block blockAtFace = polledBlock.getRelative( face );
if ( checkBlock( blockAtFace, sourceLocation ) ) {
blockBreakQuery.add( blockAtFace );
}
}
}
};
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
private void onBlockDestroy(final BlockBreakEvent event){
Block initialBlock = event.getBlock();
World world = initialBlock.getWorld();
Material initialMaterial = initialBlock.getType();
Location lookupLocation = initialBlock.getLocation();
if ( initialMaterial.toString().endsWith( "_LOG" ) ) {
for ( int y = 1; y <= 256; y++ ) {
lookupLocation.add( 0, 1, 0 );
Block blockToFall = world.getBlockAt( lookupLocation );
Location fallLocation = lookupLocation.toCenterLocation();
if ( !blockToFall.getType().toString().endsWith( "_LOG" ) ) {
break;
}
breakTree( initialBlock, event.getPlayer().getActiveItem() );
FallingBlock fallingBlock = world.spawnFallingBlock( fallLocation, blockToFall.getBlockData() );
fallingBlock.setDropItem( true );
blockToFall.setType( Material.AIR );
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment