mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2025-02-16 20:41:59 +01:00
Fixed Bed Spawns
This fixes #652 and fixes #916 This also fixes some other issues with NullPointerExceptions when trying to teleport to a bed if it was invalid.
This commit is contained in:
parent
b116effa2b
commit
dbe9494dbf
@ -35,6 +35,13 @@ public interface BlockSafety {
|
|||||||
*/
|
*/
|
||||||
boolean playerCanSpawnHereSafely(Location l);
|
boolean playerCanSpawnHereSafely(Location l);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a safe bed spawn location OR null if the bed is invalid.
|
||||||
|
* @param l The location of the bead head (block with the pillow on it).
|
||||||
|
* @return Safe location around the bed or null if no location was found.
|
||||||
|
*/
|
||||||
|
Location getSafeBedSpawn(Location l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the location of the top block at the specified {@link Location}.
|
* Gets the location of the top block at the specified {@link Location}.
|
||||||
* @param l Any {@link Location}.
|
* @param l Any {@link Location}.
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
|
|
||||||
package com.onarandombox.MultiverseCore.destination;
|
package com.onarandombox.MultiverseCore.destination;
|
||||||
|
|
||||||
|
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||||
import com.onarandombox.MultiverseCore.api.MVDestination;
|
import com.onarandombox.MultiverseCore.api.MVDestination;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -21,6 +23,7 @@ public class BedDestination implements MVDestination {
|
|||||||
|
|
||||||
private boolean isValid;
|
private boolean isValid;
|
||||||
private Location knownBedLoc;
|
private Location knownBedLoc;
|
||||||
|
private MultiverseCore plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
@ -46,7 +49,10 @@ public class BedDestination implements MVDestination {
|
|||||||
@Override
|
@Override
|
||||||
public Location getLocation(Entity entity) {
|
public Location getLocation(Entity entity) {
|
||||||
if (entity instanceof Player) {
|
if (entity instanceof Player) {
|
||||||
this.knownBedLoc = ((Player) entity).getBedSpawnLocation();
|
this.knownBedLoc = this.plugin.getBlockSafety().getSafeBedSpawn(((Player) entity).getBedSpawnLocation());
|
||||||
|
if (this.knownBedLoc == null) {
|
||||||
|
((Player) entity).sendMessage("Your bed was " + ChatColor.RED + "invalid or blocked" + ChatColor.RESET + ". Sorry.");
|
||||||
|
}
|
||||||
return this.knownBedLoc;
|
return this.knownBedLoc;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -65,7 +71,7 @@ public class BedDestination implements MVDestination {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setDestination(JavaPlugin plugin, String destination) {
|
public void setDestination(JavaPlugin plugin, String destination) {
|
||||||
// Not needed.
|
this.plugin = (MultiverseCore) plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,6 +76,10 @@ public class MVPermissions implements PermissionsInterface {
|
|||||||
* @return Whether the {@link CommandSender} can travel to the specified {@link Location}.
|
* @return Whether the {@link CommandSender} can travel to the specified {@link Location}.
|
||||||
*/
|
*/
|
||||||
public boolean canTravelFromLocation(CommandSender sender, Location location) {
|
public boolean canTravelFromLocation(CommandSender sender, Location location) {
|
||||||
|
// Now The Bed destination can return null now.
|
||||||
|
if (location == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!(sender instanceof Player)) {
|
if (!(sender instanceof Player)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -13,14 +13,24 @@ import com.onarandombox.MultiverseCore.api.Core;
|
|||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.entity.Minecart;
|
import org.bukkit.entity.Minecart;
|
||||||
import org.bukkit.entity.Vehicle;
|
import org.bukkit.entity.Vehicle;
|
||||||
|
import org.bukkit.material.Bed;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default-implementation of {@link BlockSafety}.
|
* The default-implementation of {@link BlockSafety}.
|
||||||
*/
|
*/
|
||||||
public class SimpleBlockSafety implements BlockSafety {
|
public class SimpleBlockSafety implements BlockSafety {
|
||||||
private final Core plugin;
|
private final Core plugin;
|
||||||
|
private final static Set<BlockFace> AROUND_BLOCK = new HashSet<BlockFace>(){{ add(BlockFace.NORTH); add(BlockFace.NORTH_EAST);
|
||||||
|
add(BlockFace.EAST); add(BlockFace.SOUTH_EAST);
|
||||||
|
add(BlockFace.SOUTH); add(BlockFace.SOUTH_WEST);
|
||||||
|
add(BlockFace.WEST); add(BlockFace.NORTH_WEST); }};
|
||||||
|
|
||||||
public SimpleBlockSafety(Core plugin) {
|
public SimpleBlockSafety(Core plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
@ -89,6 +99,63 @@ public class SimpleBlockSafety implements BlockSafety {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Location getSafeBedSpawn(Location l) {
|
||||||
|
// The passed location, may be null (if the bed is invalid)
|
||||||
|
if (l == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final Location trySpawn = this.getSafeSpawnAroundABlock(l);
|
||||||
|
if (trySpawn != null) {
|
||||||
|
return trySpawn;
|
||||||
|
}
|
||||||
|
Location otherBlock = this.findOtherBedPiece(l);
|
||||||
|
if (otherBlock == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Now we have 2 locations, check around each, if the type is bed, skip it.
|
||||||
|
return this.getSafeSpawnAroundABlock(otherBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a safe spawn around a location. (N,S,E,W,NE,NW,SE,SW)
|
||||||
|
* @param l Location to check around
|
||||||
|
* @return A safe location, or none if it wasn't found.
|
||||||
|
*/
|
||||||
|
private Location getSafeSpawnAroundABlock(Location l) {
|
||||||
|
Iterator<BlockFace> checkblock = AROUND_BLOCK.iterator();
|
||||||
|
while(checkblock.hasNext()) {
|
||||||
|
final BlockFace face = checkblock.next();
|
||||||
|
if (this.playerCanSpawnHereSafely(l.getBlock().getRelative(face).getLocation())) {
|
||||||
|
// Don't forget to center the player.
|
||||||
|
return l.getBlock().getRelative(face).getLocation().add(.5, 0, .5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the other bed block.
|
||||||
|
* @param checkLoc The location to check for the other piece at
|
||||||
|
* @return The location of the other bed piece, or null if it was a jacked up bed.
|
||||||
|
*/
|
||||||
|
private Location findOtherBedPiece(Location checkLoc) {
|
||||||
|
if (checkLoc.getBlock().getType() != Material.BED_BLOCK) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Construct a bed object at this location
|
||||||
|
final Bed b = new Bed(Material.BED_BLOCK, checkLoc.getBlock().getData());
|
||||||
|
if (b.isHeadOfBed()) {
|
||||||
|
return checkLoc.getBlock().getRelative(b.getFacing().getOppositeFace()).getLocation();
|
||||||
|
}
|
||||||
|
// We shouldn't ever be looking at the foot, but here's the code for it.
|
||||||
|
return checkLoc.getBlock().getRelative(b.getFacing()).getLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user