What's this? MV2 Supports multi-world bed respawns now? It sure does!

This commit is contained in:
Eric Stokes 2011-07-10 12:06:14 -06:00
parent c54a746c2f
commit 8a0301f162
7 changed files with 243 additions and 85 deletions

View File

@ -3,6 +3,8 @@ package com.onarandombox.MultiverseCore;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerBedLeaveEvent;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
@ -16,23 +18,12 @@ import com.onarandombox.MultiverseCore.event.MVRespawnEvent;
public class MVPlayerListener extends PlayerListener {
MultiverseCore plugin;
MVTeleport mvteleporter;
public MVPlayerListener(MultiverseCore plugin) {
this.plugin = plugin;
}
@Override
public void onPlayerTeleport(PlayerTeleportEvent event) {
MVPlayerSession ps = this.plugin.getPlayerSession(event.getPlayer());
ps.setRespawnWorld(event.getTo().getWorld());
}
@Override
public void onPlayerKick(PlayerKickEvent event) {
// TODO Auto-generated method stub
super.onPlayerKick(event);
}
@Override
public void onPlayerMove(PlayerMoveEvent event) {
Player p = event.getPlayer(); // Grab Player
@ -47,12 +38,20 @@ public class MVPlayerListener extends PlayerListener {
ps.loc = loc; // Update the Players Session to the new Location.
}
}
@Override
public void onPlayerBedLeave(PlayerBedLeaveEvent event) {
Location bedLoc = event.getBed().getLocation();
bedLoc = this.plugin.getTeleporter().getSafeBedDestination(bedLoc);
this.plugin.getPlayerSession(event.getPlayer()).setRespawnLocation(bedLoc);
event.getPlayer().sendMessage("You should come back here when you type '/mv sleep'!");
}
@Override
public void onPlayerChat(PlayerChatEvent event) {
// Not sure if this should be a seperat plugin... in here for now!!!
// Not sure if this should be a separate plugin... in here for now!!!
// FernFerret
if (event.isCancelled()) {
return;
}
@ -60,40 +59,46 @@ public class MVPlayerListener extends PlayerListener {
* Check whether the Server is set to prefix the chat with the World name. If not we do nothing, if so we need to check if the World has an Alias.
*/
if (this.plugin.configMV.getBoolean("worldnameprefix", true)) {
String world = event.getPlayer().getWorld().getName();
String prefix = "";
// If we're not a MV world, don't do anything
if (!this.plugin.isMVWorld(world)) {
return;
}
MVWorld mvworld = this.plugin.getMVWorld(world);
prefix = mvworld.getColoredWorldString();
String format = event.getFormat();
event.setFormat("[" + prefix + "]" + format);
}
}
@Override
public void onPlayerRespawn(PlayerRespawnEvent event) {
// TODO: Handle Global Respawn from config
// TODO: Handle Alternate Respawn from config
MVPlayerSession ps = this.plugin.getPlayerSession(event.getPlayer());
// Location newrespawn = ps.getRespawnWorld().getSpawnLocation();
Location newrespawn = event.getPlayer().getWorld().getSpawnLocation();
String respawnStyle = this.plugin.configMV.getString("notchrespawnstyle", "none");
String defaultWorld = this.plugin.configMV.getString("defaultspawnworld", "world");
boolean bedRespawn = this.plugin.configMV.getBoolean("bedrespawn", true);
Location bedRespawnLoc = this.plugin.getPlayerSession(event.getPlayer()).getBedRespawnLocation();
if (respawnStyle.equalsIgnoreCase("none")) {
if (bedRespawn && bedRespawnLoc != null) {
Location correctedBedRespawn = new Location(bedRespawnLoc.getWorld(), bedRespawnLoc.getX(), bedRespawnLoc.getY() + 1, bedRespawnLoc.getZ());
event.setRespawnLocation(correctedBedRespawn);
} else if (respawnStyle.equalsIgnoreCase("none")) {
event.setRespawnLocation(newrespawn);
} else if (respawnStyle.equalsIgnoreCase("default")) {
if (this.plugin.isMVWorld(defaultWorld)) {
event.setRespawnLocation(this.plugin.getServer().getWorld(defaultWorld).getSpawnLocation());
} else {
@ -105,7 +110,7 @@ public class MVPlayerListener extends PlayerListener {
event.setRespawnLocation(mvevent.getPlayersRespawnLocation());
}
}
@Override
public void onPlayerJoin(PlayerJoinEvent event) {
if (this.plugin.getMVWorlds().size() == 0 && this.plugin.ph.hasPermission(event.getPlayer(), "multiverse.world.import", true)) {
@ -115,9 +120,9 @@ public class MVPlayerListener extends PlayerListener {
event.getPlayer().sendMessage("If you just wanna see all of the Multiverse Help, type: " + ChatColor.GREEN + "/mv");
}
}
@Override
public void onPlayerQuit(PlayerQuitEvent event) {
}
}

View File

@ -3,24 +3,32 @@ package com.onarandombox.MultiverseCore;
import java.util.Date;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.util.config.Configuration;
import com.onarandombox.utils.BlockSafety;
public class MVPlayerSession {
private Player player; // Player holder, may be unnecessary.
public Location loc = new Location(null, 0, 0, 0); // Contain the Players Location so on player move we can compare this and check if they've moved a block.
public String portal = null; // Allow a player to target a portal to prevent them typing its name every command.
protected Location loc = new Location(null, 0, 0, 0); // Contain the Players Location so on player move we can compare this and check if they've moved a block.
private BlockSafety bs = new BlockSafety();
// Move to portals plugin
protected String portal = null; // Allow a player to target a portal to prevent them typing its name every command.
// Move to portals plugin
public Location coord1 = null; // Coordinate 1 (Left Click)
public Location coord2 = null; // Coordinate 2 (Right Click)
private Long teleportLast = 0L; // Timestamp for the Players last Portal Teleportation.
private Long messageLast = 0L; // Timestamp for the Players last Alert Message.
private World currentSpawn;
private Location bedSpawn;
// Beds are 2 blocks, thus we need to store both places
private Location bedA;
private Location bedB;
private Configuration config; // Configuration file to find out Cooldown Timers.
@ -28,7 +36,7 @@ public class MVPlayerSession {
this.player = player;
this.loc = player.getLocation();
this.config = config;
this.currentSpawn = player.getWorld();
this.bedSpawn = null;
}
/**
@ -40,6 +48,7 @@ public class MVPlayerSession {
/**
* Grab whether the cooldown on Portal use has expired or not.
*
* @return
*/
public boolean getTeleportable() {
@ -53,6 +62,7 @@ public class MVPlayerSession {
/**
* Send a Message to the Player as long as enough time has passed since the last message.
*
* @param msg
*/
public void message(String msg) {
@ -63,11 +73,42 @@ public class MVPlayerSession {
}
}
public void setRespawnWorld(World world) {
this.currentSpawn = world;
public void setRespawnLocation(Location location) {
this.bedSpawn = location;
}
public World getRespawnWorld() {
return this.currentSpawn;
//
// public Location getRespawnLocation() {
// if (this.bedSpawn != null && !this.bs.playerCanSpawnHereSafely(this.bedSpawn)) {
// this.bedSpawn = null;
// }
// return this.bedSpawn;
// }
// This one simply spawns the player closer to the bed.
public Location getBedRespawnLocation() {
// There is a bedrespawn set
if (this.bedSpawn != null) {
if (!this.bs.playerCanSpawnHereSafely(this.bedSpawn) || !bedStillExists(this.bedSpawn)) {
this.bedSpawn = null;
return this.bedSpawn;
}
Location actualRespawn = this.bedSpawn;
Location bedRespawn = new Location(actualRespawn.getWorld(), actualRespawn.getX(), actualRespawn.getY(), actualRespawn.getZ());
bedRespawn.setY(bedRespawn.getY() - .25);
return bedRespawn;
}
return null;
}
private boolean bedStillExists(Location bedSpawn) {
System.out.print("Dangers:");
this.bs.showDangers(bedSpawn);
Location locationDown = new Location(bedSpawn.getWorld(), bedSpawn.getX(), bedSpawn.getY(), bedSpawn.getZ());
locationDown.setY(locationDown.getY() - 1);
if (locationDown.getBlock().getType() != Material.BED_BLOCK) {
return false;
}
return true;
}
}

View File

@ -12,16 +12,16 @@ import org.bukkit.entity.Player;
import com.onarandombox.utils.BlockSafety;
public class MVTeleport {
MultiverseCore plugin;
BlockSafety bs = new BlockSafety();
private static final Logger log = Logger.getLogger("Minecraft");
public MVTeleport(MultiverseCore plugin) {
this.plugin = plugin;
}
/**
* TODO: Sort out JavaDoc
*
@ -35,15 +35,15 @@ public class MVTeleport {
if (l.getWorld().getName().equalsIgnoreCase(w.getName())) {
return l;
}
double x, y, z;
// Grab the Scaling value for each world.
double srcComp = this.plugin.getMVWorld(l.getWorld().getName()).getScaling();
double trgComp = this.plugin.getMVWorld(w.getName()).getScaling();
// MultiverseCore.debugMsg(p.getName() + " -> " + p.getWorld().getName() + "(" + srcComp + ") -> " + w.getName() + "(" + trgComp + ")");
// If the Targets Compression is 0 then we teleport them to the Spawn of the World.
if (trgComp == 0.0) {
x = w.getSpawnLocation().getX();
@ -56,7 +56,26 @@ public class MVTeleport {
}
return new Location(w, x, y, z);
}
/**
* This method will be specific to beds, and check on top of the bed then around it.
*
* @return
*/
public Location getSafeBedDestination(Location bedLocation) {
System.out.print(bedLocation);
Location idealLocation = bedLocation;
idealLocation.setY(idealLocation.getY() + 1);
idealLocation.setX(idealLocation.getX() + .5);
idealLocation.setZ(idealLocation.getZ() + .5);
System.out.print(idealLocation);
if (this.bs.playerCanSpawnHereSafely(idealLocation)) {
System.out.print(idealLocation);
return bedLocation;
}
return null;
}
/**
* This function gets a safe place to teleport to.
*
@ -69,12 +88,12 @@ public class MVTeleport {
double y = l.getY();
double z = l.getZ();
World w = l.getWorld();
// To make things easier we'll start with the Y Coordinate on top of a Solid Block.
// while (bs.blockIsAboveAir(w, x, y, z)) {
// y--;
// }
double i = 0, r = 0, aux = -1;
for (r = 0; r < 32; r++) {
for (i = x - r; i <= x + r; i++) {
@ -106,17 +125,17 @@ public class MVTeleport {
break;
}
}
if (aux == -1) {
log.warning("Uh oh, no safe location.");
return null;
}
//log.info("Target location (safe): " + x + ", " + aux + ", " + z);
// log.info("Target location (safe): " + x + ", " + aux + ", " + z);
return new Location(w, x, aux, z);
}
/**
* Check the Column given to see if there is an available safe spot.
*
@ -137,7 +156,7 @@ public class MVTeleport {
}
return -1;
}
/**
* Find a portal around the given location and return a new location.
*
@ -156,7 +175,7 @@ public class MVTeleport {
}
}
}
// For each column try to find a portal block
for (Block col : columns) {
for (int y = 0; y <= 127; y++) {

View File

@ -65,7 +65,7 @@ public class MultiverseCore extends JavaPlugin {
private HashMap<String, MVWorld> worlds = new HashMap<String, MVWorld>();
// HashMap to contain information relating to the Players.
public HashMap<String, MVPlayerSession> playerSessions = new HashMap<String, MVPlayerSession>();
private HashMap<String, MVPlayerSession> playerSessions;
private PurgeWorlds worldPurger;
public GenericBank bank = null;
public AllPay banker = new AllPay(this, "[Multiverse-Core] ");;
@ -97,6 +97,8 @@ public class MultiverseCore extends JavaPlugin {
this.worldPurger = new PurgeWorlds(this);
// Call the Function to assign all the Commands to their Class.
this.registerCommands();
this.playerSessions = new HashMap<String, MVPlayerSession>();
// Start the Update Checker
// updateCheck = new UpdateChecker(this.getDescription().getName(), this.getDescription().getVersion());
@ -119,6 +121,7 @@ public class MultiverseCore extends JavaPlugin {
pm.registerEvent(Event.Type.PLAYER_KICK, this.playerListener, Priority.Highest, this);
pm.registerEvent(Event.Type.PLAYER_RESPAWN, this.playerListener, Priority.Normal, this);
pm.registerEvent(Event.Type.PLAYER_CHAT, this.playerListener, Priority.Normal, this);
pm.registerEvent(Event.Type.PLAYER_BED_LEAVE, this.playerListener, Priority.Normal, this);
pm.registerEvent(Event.Type.ENTITY_REGAIN_HEALTH, this.entityListener, Priority.Normal, this);
pm.registerEvent(Event.Type.ENTITY_DAMAGE, this.entityListener, Priority.Normal, this); // To Allow/Disallow fake PVP
@ -169,7 +172,7 @@ public class MultiverseCore extends JavaPlugin {
*/
private void registerCommands() {
// Page 1
this.commandHandler.registerCommand(new HelpCommand(this));
this.commandHandler.registerCommand(new CoordCommand(this));
this.commandHandler.registerCommand(new TeleportCommand(this));
this.commandHandler.registerCommand(new ListCommand(this));
@ -193,6 +196,8 @@ public class MultiverseCore extends JavaPlugin {
this.commandHandler.registerCommand(new ModifyCommand(this));
this.commandHandler.registerCommand(new EnvironmentCommand(this));
this.commandHandler.registerCommand(new PurgeCommand(this));
this.commandHandler.registerCommand(new SleepCommand(this));
this.commandHandler.registerCommand(new HelpCommand(this));
}
/**

View File

@ -0,0 +1,48 @@
package com.onarandombox.MultiverseCore.command.commands;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.World.Environment;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.onarandombox.MultiverseCore.MVPlayerSession;
import com.onarandombox.MultiverseCore.MVWorld;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.pneumaticraft.commandhandler.Command;
public class SleepCommand extends Command {
public SleepCommand(MultiverseCore plugin) {
super(plugin);
this.commandName = "Go To Sleep";
this.commandDesc = "Takes you the latest bed you've slept in.";
this.commandUsage = "/mv sleep";
this.minimumArgLength = 0;
this.maximumArgLength = 0;
this.commandKeys.add("mv sleep");
this.permission = "multiverse.sleep";
this.opRequired = false;
}
@Override
public void runCommand(CommandSender sender, List<String> args) {
Player p = null;
if (sender instanceof Player) {
p = (Player) sender;
}
if(p == null) {
return;
}
MVPlayerSession session = ((MultiverseCore) this.plugin).getPlayerSession(p);
if(session.getBedRespawnLocation() != null) {
p.teleport(session.getBedRespawnLocation());
} else {
sender.sendMessage("Hmm this is awkward...");
sender.sendMessage("Something is wrong with your bed.");
sender.sendMessage("It has either been destroyed or obstructed.");
}
}
}

View File

@ -1,5 +1,6 @@
package com.onarandombox.utils;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
@ -13,12 +14,19 @@ public class BlockSafety {
* @param z
* @return
*/
public boolean blockIsAboveAir(World world, double x, double y, double z) {
return (world.getBlockAt((int) Math.floor(x), (int) Math.floor(y - 1), (int) Math.floor(z)).getType() == Material.AIR);
private boolean blockIsAboveAir(Location l) {
Location downOne = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
downOne.setY(downOne.getY() - 1);
return (downOne.getBlock().getType() == Material.AIR);
}
public boolean blockIsNotSafe(World world, double x, double y, double z) {
Location l = new Location(world, x, y, z);
return !playerCanSpawnHereSafely(l);
}
/**
* This function checks whether the block at the coordinates given is safe or not by checking for Laval/Fire/Air etc.
* This function checks whether the block at the coordinates given is safe or not by checking for Laval/Fire/Air etc. This also ensures there is enough space for a player to spawn!
*
* @param world
* @param x
@ -26,26 +34,54 @@ public class BlockSafety {
* @param z
* @return
*/
public boolean blockIsNotSafe(World world, double x, double y, double z) {
if (world.getBlockAt((int) Math.floor(x), (int) Math.floor(y), (int) Math.floor(z)).getType() != Material.AIR || world.getBlockAt((int) Math.floor(x), (int) Math.floor(y + 1), (int) Math.floor(z)).getType() != Material.AIR)
return true;
public boolean playerCanSpawnHereSafely(Location l) {
Location actual = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
Location upOne = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
Location downOne = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
upOne.setY(upOne.getY() + 1);
downOne.setY(downOne.getY() - 1);
if ((world.getBlockAt((int) Math.floor(x), (int) Math.floor(y - 1), (int) Math.floor(z)).getType() == Material.LAVA))
return true;
System.out.print("Location Up: " + upOne.getBlock().getType());
System.out.print(" " + upOne);
System.out.print("Location: " + actual.getBlock().getType());
System.out.print(" " + actual);
System.out.print("Location Down: " + downOne.getBlock().getType());
System.out.print(" " + downOne);
if ((world.getBlockAt((int) Math.floor(x), (int) Math.floor(y - 1), (int) Math.floor(z)).getType() == Material.STATIONARY_LAVA))
return true;
if ((world.getBlockAt((int) Math.floor(x), (int) Math.floor(y - 1), (int) Math.floor(z)).getType() == Material.FIRE))
return true;
if ((world.getBlockAt((int) Math.floor(x), (int) Math.floor(y), (int) Math.floor(z)).getType() == Material.FIRE))
return true;
if (blockIsAboveAir(world, x, y, z))
return true;
return false;
if (actual.getBlock().getType() != Material.AIR || upOne.getBlock().getType() != Material.AIR)
return false;
if (downOne.getBlock().getType() == Material.LAVA)
return false;
if (downOne.getBlock().getType() == Material.STATIONARY_LAVA)
return false;
if (downOne.getBlock().getType() == Material.FIRE)
return false;
if (actual.getBlock().getType() == Material.FIRE)
return false;
if (blockIsAboveAir(actual))
return false;
return true;
}
public void showDangers(Location l) {
Location actual = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
Location upOne = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
Location downOne = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
upOne.setY(upOne.getY() + 1);
downOne.setY(downOne.getY() - 1);
System.out.print("Location Up: " + upOne.getBlock().getType());
System.out.print(" " + upOne);
System.out.print("Location: " + actual.getBlock().getType());
System.out.print(" " + actual);
System.out.print("Location Down: " + downOne.getBlock().getType());
System.out.print(" " + downOne);
}
}

View File

@ -41,4 +41,8 @@ disableautoheal: false
# This will use the old style of PVP prevention so you can have zones of PVP
# Players will be notified when they punch/shoot and it's not allowed.
fakepvp: false
fakepvp: false
# When this is enabled, users will spawn at their last bed slept at. If the bed is destroyed or obstructed,
# they will spawn according to how you have 'notchrespawnstyle' set.
bedrespawn: true