Skip to content

Instantly share code, notes, and snippets.

@sk89q
Created December 17, 2011 03:06
Show Gist options
  • Save sk89q/1489005 to your computer and use it in GitHub Desktop.
Save sk89q/1489005 to your computer and use it in GitHub Desktop.
// Available under GPLv3
package com.sk89q.skcraft;
import java.util.Random;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Enderman;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.Event.Type;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.ItemStack;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.rebar.AbstractComponent;
import com.sk89q.rebar.BukkitEvent;
import com.sk89q.rebar.Rebar;
import com.sk89q.rebar.util.ChatUtil;
import com.sk89q.rebar.util.PlayerUtil;
public class EnderPearlHomes extends AbstractComponent {
private static Random random = new Random();
public void initialize() {
Rebar.getInstance().registerEvents(new EntityListener());
Rebar.getInstance().registerEvents(new PlayerListener());
Rebar.getInstance().registerCommands(Commands.class, this);
}
public void shutdown() {
}
public class EntityListener extends org.bukkit.event.entity.EntityListener {
@Override
@BukkitEvent(type = Type.ENTITY_DEATH)
public void onEntityDeath(EntityDeathEvent event) {
Entity ent = event.getEntity();
if (ent instanceof Enderman) {
for (int i = 0; i < random.nextInt(5) + 2; i++) {
event.getDrops().add(new ItemStack(Material.ENDER_PEARL, 1));
}
}
}
}
public class PlayerListener extends org.bukkit.event.player.PlayerListener {
@Override
@BukkitEvent(type = Type.PLAYER_TELEPORT)
public void onPlayerTeleport(PlayerTeleportEvent event) {
Player player = event.getPlayer();
TeleportCause cause = event.getCause();
Location to = event.getTo();
if (cause == TeleportCause.ENDER_PEARL) {
if (to.distanceSquared(player.getLocation()) < 1.5 * 1.5) {
Location bedLoc = player.getBedSpawnLocation(); // NOT multi-world friendly apparently; you will have to fix this
if (bedLoc == null) {
ChatUtil.msg(player, ChatColor.GOLD, "Use a bed to set a home to able to return there when throwing an ender pearl up.");
} else {
ChatUtil.msg(player, ChatColor.GOLD, "To home you go!");
Location betterLoc = PlayerUtil.findFreePosition(player, bedLoc);
event.setTo(betterLoc);
}
}
}
}
@Override
@BukkitEvent(type = Event.Type.PLAYER_RESPAWN)
public void onPlayerRespawn(PlayerRespawnEvent event) {
Player player = event.getPlayer();
Location bedLoc = player.getBedSpawnLocation();
if (bedLoc != null) {
Location betterLoc = PlayerUtil.findFreePosition(player, bedLoc);
if (betterLoc != null) {
event.setRespawnLocation(betterLoc);
}
}
}
}
public static class Commands {
public Commands(EnderPearlHomes component) {
}
@Command(aliases = {"sethome"}, desc = "Set your home")
public void sethome(CommandContext context, CommandSender sender) {
ChatUtil.msg(sender, ChatColor.YELLOW, "To set a home, sleep in a bed during the day or night. (How do you craft a bed? Use /recipe bed)");
}
@Command(aliases = {"home"}, desc = "Go to your home")
public void home(CommandContext context, CommandSender sender) {
ChatUtil.msg(sender, ChatColor.YELLOW, "To go to your home (set with a bed), throw an ender pearl (get those from slaying Endermen) at your feet.");
}
}
}
// Available under GPLv3
package com.sk89q.rebar.util;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.sk89q.worldedit.blocks.BlockType;
public class PlayerUtil {
private PlayerUtil() {
}
public static Location findFreePosition(Player player, Location pos) {
World world = player.getWorld();
// Let's try going down
Block block = pos.getBlock().getRelative(0, 1, 0);
if (!block.getChunk().isLoaded()) {
block.getChunk().load();
}
int free = 0;
// Look for ground
while (block.getY() > 0 && BlockType.canPassThrough(block.getTypeId())) {
free++;
block = block.getRelative(0, -1, 0);
}
if (block.getY() == 0) return null; // No ground below!
if (free >= 2) {
if (BlockMaterialUtil.isDangerous(block.getType())) {
return null; // Not safe
}
return block.getRelative(0, 1, 0).getLocation().add(new Vector(0.5, 0, 0.5));
}
// Let's try going up
block = pos.getBlock().getRelative(0, -1, 0);
free = 0;
boolean foundGround = false;
while (block.getY() <= world.getMaxHeight() + 1) {
if (BlockType.canPassThrough(block.getTypeId())) {
free++;
} else {
free = 0;
foundGround = !BlockMaterialUtil.isDangerous(block.getType());
}
if (foundGround && free == 2) {
return block.getRelative(0, -1, 0).getLocation().add(new Vector(0.5, 0.5, 0.5));
}
block = block.getRelative(0, 1, 0);
}
return null;
}
}
@pirogoeth
Copy link

I want Rebar so badly >.<

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment