Skip to content

Instantly share code, notes, and snippets.

@aadnk
Created September 26, 2012 15:09
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save aadnk/3788593 to your computer and use it in GitHub Desktop.
Save aadnk/3788593 to your computer and use it in GitHub Desktop.
A way of enabling block breaking from far away
package com.comphenix.example;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.server.Packet55BlockBreakAnimation;
import org.bukkit.Server;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitScheduler;
public class ExampleListener implements Listener {
private final static int PLAYER_REACH = 60;
private final static int MINIMUM_DISTANCE = 4;
// Number of ticks it takes to break a block
private final static int BREAK_TIME = 40;
private Map<String, TaskedRunnable> playerClicking = new HashMap<String, TaskedRunnable>();
private Plugin plugin;
private Server server;
private BukkitScheduler scheduler;
public ExampleListener(Plugin plugin) {
this.plugin = plugin;
this.server = plugin.getServer();
this.scheduler = server.getScheduler();
}
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerInteractEvent(PlayerInteractEvent event) {
Player player = event.getPlayer();
int dimension = ((CraftWorld) player.getWorld()).getHandle().dimension;
int breakTime = BREAK_TIME;
if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
// Cancel previous actions
TaskedRunnable previous = playerClicking.get(player.getName());
if (previous != null) {
previous.cancel();
}
Block block = player.getTargetBlock(null, PLAYER_REACH);
// No need if we're within the default distance
if (block.getLocation().distance(player.getLocation()) >= MINIMUM_DISTANCE) {
TaskedRunnable tasked = new TaskedRunnable(player, block, dimension, breakTime);
int taskID = scheduler.scheduleSyncRepeatingTask(plugin, tasked, 1L, 1L);
// Save the task ID
tasked.setTaskID(taskID);
playerClicking.put(player.getName(), tasked);
}
}
}
private class TaskedRunnable implements Runnable {
private static final int BLOCK_BREAK_MAX = 11;
private int counter = 0;
private int taskID;
private Player player;
private Block block;
private int breakTime;
private int dimension;
private int lastDamage = -1;
public TaskedRunnable(Player player, Block block, int dimension, int breakTime) {
this.player = player;
this.block = block;
this.dimension = dimension;
this.breakTime = breakTime;
}
public void setTaskID(int taskID) {
this.taskID = taskID;
}
@Override
public void run() {
double progress = counter / (double)breakTime;
int damage = (int) (progress * BLOCK_BREAK_MAX);
// No need to send the same damage
if (damage != lastDamage) {
Block newTarget = player.getTargetBlock(null, PLAYER_REACH);
// Make sure we're looking at the same block
if (newTarget == null || !block.getLocation().equals(newTarget.getLocation())) {
cancel();
return;
}
sendBlockBreak(damage);
lastDamage = damage;
}
counter++;
System.out.println(String.format("Counter: %s Damage: %s", counter, damage));
if (counter >= breakTime) {
block.breakNaturally();
scheduler.cancelTask(taskID);
}
}
private void sendBlockBreak(int damage) {
Packet55BlockBreakAnimation breakBlockPacket = new Packet55BlockBreakAnimation(
0, //player.getEntityId()
block.getX(), block.getY(), block.getZ(),
damage);
((CraftServer) server).getHandle().sendPacketNearby(
block.getX(), block.getY(), block.getZ(),
PLAYER_REACH * 2, dimension, breakBlockPacket);
}
public void cancel() {
playerClicking.remove(player.getName());
scheduler.cancelTask(taskID);
// Reset block
sendBlockBreak(10);
System.out.println("Cancelled");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment