Created
November 26, 2012 06:28
-
-
Save aadnk/4146843 to your computer and use it in GitHub Desktop.
Path-find to a nearby block lit by sunlight
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.comphenix.example; | |
import net.minecraft.server.EntityPlayer; | |
import net.minecraft.server.PathEntity; | |
import net.minecraft.server.PathPoint; | |
import net.minecraft.server.WorldServer; | |
import org.bukkit.ChatColor; | |
import org.bukkit.DyeColor; | |
import org.bukkit.Location; | |
import org.bukkit.Material; | |
import org.bukkit.World; | |
import org.bukkit.block.Block; | |
import org.bukkit.command.Command; | |
import org.bukkit.command.CommandSender; | |
import org.bukkit.craftbukkit.CraftWorld; | |
import org.bukkit.craftbukkit.entity.CraftPlayer; | |
import org.bukkit.entity.Entity; | |
import org.bukkit.entity.Player; | |
import org.bukkit.event.Listener; | |
import org.bukkit.plugin.java.JavaPlugin; | |
public class PathFinderExample extends JavaPlugin implements Listener { | |
@Override | |
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { | |
if (args.length > 0) { | |
sender.sendMessage("This command doesn't take any arguments."); | |
return true; | |
} | |
if (label.equalsIgnoreCase("performaction")) { | |
if (sender instanceof Player) | |
performAction((Player) sender, args); | |
else | |
performAction(sender); | |
return true; | |
} | |
return false; | |
} | |
private void performAction(CommandSender sender) { | |
sender.sendMessage("Cannot perform action on console."); | |
} | |
private void performAction(Player sender, String[] args) { | |
PathEntity path = getSurfacePath(sender, 10); | |
// Print the result | |
if (path != null) { | |
displayPathLocally(sender, path, Material.WOOL, DyeColor.GREEN.getData()); | |
} else { | |
sender.sendMessage(ChatColor.RED + "Unable to find path."); | |
} | |
} | |
private PathEntity getSurfacePath(Player player, int maximumDistance) { | |
World world = player.getWorld(); | |
Location center = player.getLocation(); | |
int centerX = center.getBlockX(); | |
int centerZ = center.getBlockZ(); | |
int maximumSquared = maximumDistance * maximumDistance; | |
// Find suitable locations in a 20x20 rectangle | |
for (int dX = -maximumDistance; dX < maximumDistance; dX++) { | |
for (int dZ = -maximumDistance; dZ < maximumDistance; dZ++) { | |
Block highest = world.getHighestBlockAt(centerX + dX, centerZ + dZ); | |
// The shortest (direct) distance must be valid first and foremost | |
if (highest.getLocation().distanceSquared(center) < maximumSquared) { | |
PathEntity path = getPath(player, highest.getLocation(), maximumDistance); | |
if (path != null) { | |
return path; | |
} | |
} | |
} | |
} | |
return null; | |
} | |
private PathEntity getPath(Entity source, Location destination, int maximumDistance) { | |
WorldServer nmsWorld = ((CraftWorld) source.getWorld()).getHandle(); | |
EntityPlayer entity = ((CraftPlayer) source).getHandle(); | |
return nmsWorld.a(entity, destination.getBlockX(), destination.getBlockY(), destination.getBlockZ(), | |
maximumDistance, true, false, false, true); | |
} | |
private void displayPathLocally(Player sender, PathEntity path, Material material, int data) { | |
for (int i = 0; i < path.d(); i++) { | |
PathPoint point = path.a(i); | |
Location loc = new Location(sender.getWorld(), point.a, point.b, point.c); | |
// "Display" the path | |
sender.sendBlockChange(loc, material, (byte) (data & 0xFF)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment