mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2025-02-16 04:21:31 +01:00
Merge pull request #3151 from Multiverse/ben/mv5/block-safety
ben/mv5/block-safety
This commit is contained in:
commit
3a9eb88197
@ -10,6 +10,7 @@ import org.jvnet.hk2.annotations.Contract;
|
||||
/**
|
||||
* Used to get block/location-related information.
|
||||
*/
|
||||
@Deprecated
|
||||
@Contract
|
||||
public interface BlockSafety {
|
||||
/**
|
||||
|
@ -112,6 +112,14 @@ public interface MVConfig {
|
||||
*/
|
||||
void setFirstSpawnOverride(boolean firstSpawnOverride);
|
||||
|
||||
void setSafeLocationHorizontalSearchRadius(int searchRadius);
|
||||
|
||||
int getSafeLocationHorizontalSearchRadius();
|
||||
|
||||
void setSafeLocationVerticalSearchRadius(int searchRadius);
|
||||
|
||||
int getSafeLocationVerticalSearchRadius();
|
||||
|
||||
/**
|
||||
* Gets firstSpawnOverride.
|
||||
* @return firstSpawnOverride.
|
||||
|
@ -189,6 +189,26 @@ public class MVCoreConfig implements MVConfig {
|
||||
configHandle.set(configNodes.FIRST_SPAWN_OVERRIDE, firstSpawnOverride);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSafeLocationHorizontalSearchRadius(int searchRadius) {
|
||||
configHandle.set(configNodes.SAFE_LOCATION_HORIZONTAL_SEARCH_RADIUS, searchRadius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSafeLocationHorizontalSearchRadius() {
|
||||
return configHandle.get(configNodes.SAFE_LOCATION_HORIZONTAL_SEARCH_RADIUS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSafeLocationVerticalSearchRadius(int searchRadius) {
|
||||
configHandle.set(configNodes.SAFE_LOCATION_VERTICAL_SEARCH_RADIUS, searchRadius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSafeLocationVerticalSearchRadius() {
|
||||
return configHandle.get(configNodes.SAFE_LOCATION_VERTICAL_SEARCH_RADIUS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFirstSpawnOverride() {
|
||||
return configHandle.get(configNodes.FIRST_SPAWN_OVERRIDE);
|
||||
|
@ -130,6 +130,24 @@ class MVCoreConfigNodes {
|
||||
.name("teleport-intercept")
|
||||
.build());
|
||||
|
||||
final ConfigNode<Integer> SAFE_LOCATION_HORIZONTAL_SEARCH_RADIUS = node(ConfigNode.builder("teleport.safe-location-horizontal-search-radius", Integer.class)
|
||||
.comment("")
|
||||
.comment("Sets the horizontal (x and z-axis) search radius for finding a safe location to teleport to.")
|
||||
.comment("Increasing this value will widen the search area at the cost of performance.")
|
||||
.comment("To disable, set to 0.")
|
||||
.defaultValue(3)
|
||||
.name("safe-location-horizontal-search-radius")
|
||||
.build());
|
||||
|
||||
final ConfigNode<Integer> SAFE_LOCATION_VERTICAL_SEARCH_RADIUS = node(ConfigNode.builder("teleport.safe-location-vertical-search-radius", Integer.class)
|
||||
.comment("")
|
||||
.comment("Sets the vertical (y-axis) search radius for finding a safe location to teleport to.")
|
||||
.comment("Increasing this value will widen the search area at the cost of performance.")
|
||||
.comment("To disable, set to 0.")
|
||||
.defaultValue(3)
|
||||
.name("safe-location-vertical-search-radius")
|
||||
.build());
|
||||
|
||||
private final ConfigHeaderNode SPAWN_HEADER = node(ConfigHeaderNode.builder("spawn")
|
||||
.comment("")
|
||||
.comment("")
|
||||
|
@ -8,7 +8,6 @@
|
||||
package org.mvplugins.multiverse.core.listeners;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
@ -24,22 +23,20 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerPortalEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
|
||||
import org.mvplugins.multiverse.core.MultiverseCore;
|
||||
import org.mvplugins.multiverse.core.api.BlockSafety;
|
||||
import org.mvplugins.multiverse.core.commandtools.MVCommandManager;
|
||||
import org.mvplugins.multiverse.core.config.MVCoreConfig;
|
||||
import org.mvplugins.multiverse.core.destination.DestinationInstance;
|
||||
import org.mvplugins.multiverse.core.destination.DestinationsProvider;
|
||||
import org.mvplugins.multiverse.core.economy.MVEconomist;
|
||||
import org.mvplugins.multiverse.core.event.MVRespawnEvent;
|
||||
import org.mvplugins.multiverse.core.teleportation.AdvancedBlockSafety;
|
||||
import org.mvplugins.multiverse.core.teleportation.AsyncSafetyTeleporter;
|
||||
import org.mvplugins.multiverse.core.teleportation.TeleportQueue;
|
||||
import org.mvplugins.multiverse.core.utils.result.ResultChain;
|
||||
@ -58,7 +55,7 @@ public class MVPlayerListener implements CoreListener {
|
||||
private final Plugin plugin;
|
||||
private final MVCoreConfig config;
|
||||
private final Provider<WorldManager> worldManagerProvider;
|
||||
private final BlockSafety blockSafety;
|
||||
private final AdvancedBlockSafety blockSafety;
|
||||
private final AsyncSafetyTeleporter safetyTeleporter;
|
||||
private final Server server;
|
||||
private final TeleportQueue teleportQueue;
|
||||
@ -75,7 +72,7 @@ public class MVPlayerListener implements CoreListener {
|
||||
MultiverseCore plugin,
|
||||
MVCoreConfig config,
|
||||
Provider<WorldManager> worldManagerProvider,
|
||||
BlockSafety blockSafety,
|
||||
AdvancedBlockSafety blockSafety,
|
||||
AsyncSafetyTeleporter safetyTeleporter,
|
||||
Server server,
|
||||
TeleportQueue teleportQueue,
|
||||
@ -317,6 +314,7 @@ public class MVPlayerListener implements CoreListener {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when a player actually portals via a vanilla style portal.
|
||||
* @param event The Event that was fired.
|
||||
|
@ -0,0 +1,394 @@
|
||||
package org.mvplugins.multiverse.core.teleportation;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import io.vavr.control.Option;
|
||||
import jakarta.inject.Inject;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.Rail;
|
||||
import org.bukkit.entity.Minecart;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
import org.mvplugins.multiverse.core.api.LocationManipulation;
|
||||
import org.mvplugins.multiverse.core.config.MVCoreConfig;
|
||||
|
||||
/**
|
||||
* Used to check get or find block/location-related information.
|
||||
*/
|
||||
@Service
|
||||
public class AdvancedBlockSafety {
|
||||
|
||||
private final MVCoreConfig config;
|
||||
private final LocationManipulation locationManipulation;
|
||||
|
||||
@Inject
|
||||
AdvancedBlockSafety(@NotNull MVCoreConfig config, @NotNull LocationManipulation locationManipulation) {
|
||||
this.config = config;
|
||||
this.locationManipulation = locationManipulation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to check if a block is above air.
|
||||
*
|
||||
* @param location The location to check.
|
||||
* @return True if the block at that {@link Location} is above air.
|
||||
*/
|
||||
public boolean isBlockAboveAir(Location location) {
|
||||
return location.getBlock().getRelative(0, -1, 0).getType().isAir();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an entity would be on track at the specified {@link Location}.
|
||||
*
|
||||
* @param location The location to check.
|
||||
* @return True if an entity would be on tracks at the specified {@link Location}.
|
||||
*/
|
||||
public boolean isEntityOnTrack(Location location) {
|
||||
return location.getBlock().getBlockData() instanceof Rail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location of the highest spawnable block (i.e. y-axis) at the specified {@link Location}.
|
||||
*
|
||||
* @param location The location
|
||||
* @return The location if found, null of all blocks are unsafe.
|
||||
*/
|
||||
public Location getTopBlock(Location location) {
|
||||
Location check = location.clone();
|
||||
int maxHeight = Option.of(location.getWorld()).map(World::getMaxHeight).getOrElse(127);
|
||||
check.setY(maxHeight);
|
||||
while (check.getY() > 0) {
|
||||
if (canSpawnAtLocationSafely(check)) {
|
||||
return check;
|
||||
}
|
||||
check.setY(check.getY() - 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location of the lowest spawnable block (i.e. y-axis) at the specified {@link Location}.
|
||||
*
|
||||
* @param location The location
|
||||
* @return The location if found, null of all blocks are unsafe.
|
||||
*/
|
||||
public Location getBottomBlock(Location location) {
|
||||
Location check = location.clone();
|
||||
int minHeight = Option.of(location.getWorld()).map(World::getMinHeight).getOrElse(0);
|
||||
check.setY(minHeight);
|
||||
while (check.getY() < 127) { // SUPPRESS CHECKSTYLE: MagicNumberCheck
|
||||
if (canSpawnAtLocationSafely(check)) {
|
||||
return check;
|
||||
}
|
||||
check.setY(check.getY() + 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified {@link Minecart} can spawn safely.
|
||||
*
|
||||
* @param cart The {@link Minecart}.
|
||||
* @return True if the minecart can spawn safely.
|
||||
*/
|
||||
public boolean canSpawnCartSafely(Minecart cart) {
|
||||
if (isBlockAboveAir(cart.getLocation())) {
|
||||
return true;
|
||||
}
|
||||
return isEntityOnTrack(locationManipulation.getNextBlock(cart));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified {@link Vehicle} can spawn safely.
|
||||
*
|
||||
* @param vehicle The {@link Vehicle}.
|
||||
* @return True if the vehicle can spawn safely.
|
||||
*/
|
||||
public boolean canSpawnVehicleSafely(Vehicle vehicle) {
|
||||
return isBlockAboveAir(vehicle.getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks whether the block at the coordinates given is safe or not by checking for Lava/Fire/Air
|
||||
* etc. This also ensures there is enough space for a player to spawn!
|
||||
*
|
||||
* @param location The {@link Location}
|
||||
* @return Whether the player can spawn safely at the given {@link Location}
|
||||
*/
|
||||
public boolean canSpawnAtLocationSafely(@NotNull Location location) {
|
||||
return canSpawnAtBlockSafely(location.getBlock());
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks whether the block at the coordinates given is safe or not by checking for Lava/Fire/Air
|
||||
* etc. This also ensures there is enough space for a player to spawn!
|
||||
*
|
||||
* @param block The {@link Block}
|
||||
* @return Whether the player can spawn safely at the given {@link Location}
|
||||
*/
|
||||
public boolean canSpawnAtBlockSafely(@NotNull Block block) {
|
||||
Logging.finest("Checking spawn safety for location: %s, %s, %s", block.getX(), block.getY(), block.getZ());
|
||||
if (isUnsafeSpawnBody(block)) {
|
||||
// Player body will be stuck in solid
|
||||
Logging.finest("Unsafe location for player's body.");
|
||||
return false;
|
||||
}
|
||||
Block airBlockForHead = block.getRelative(0, 1, 0);
|
||||
if (isUnsafeSpawnBody(airBlockForHead)) {
|
||||
// Player's head will be stuck in solid
|
||||
Logging.finest("Unsafe location for player's head.");
|
||||
return false;
|
||||
}
|
||||
Block standingOnBlock = block.getRelative(0, -1, 0);
|
||||
if (isUnsafeSpawnPlatform(standingOnBlock)) {
|
||||
// Player will drop down
|
||||
Logging.finest("Unsafe location due to invalid platform.");
|
||||
return false;
|
||||
}
|
||||
Logging.finest("Location is safe.");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Player's body must be in non-solid block that is non-harming.
|
||||
*
|
||||
* @param block The block
|
||||
* @return True if the block is unsafe
|
||||
*/
|
||||
private boolean isUnsafeSpawnBody(@NotNull Block block) {
|
||||
Material blockMaterial = block.getType();
|
||||
return blockMaterial.isSolid() || blockMaterial == Material.FIRE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Player must stand on solid ground, or water that is only 1 block deep to prevent drowning.
|
||||
*
|
||||
* @param block The block
|
||||
* @return True if the block is unsafe
|
||||
*/
|
||||
private boolean isUnsafeSpawnPlatform(@NotNull Block block) {
|
||||
return !block.getType().isSolid() || isDeepWater(block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Water that is 2 or more block deep
|
||||
*
|
||||
* @param block The block
|
||||
* @return True if the block is unsafe
|
||||
*/
|
||||
private boolean isDeepWater(@NotNull Block block) {
|
||||
if (block.getType() != Material.WATER) {
|
||||
return false;
|
||||
}
|
||||
return block.getRelative(0, -1, 0).getType() == Material.WATER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the closest possible safe location around the given location with the configured search radius.
|
||||
*
|
||||
* @param location The target location to find
|
||||
* @return The safe location if found, otherwise null.
|
||||
*/
|
||||
@Nullable
|
||||
public Location findSafeSpawnLocation(@NotNull Location location) {
|
||||
return findSafeSpawnLocation(
|
||||
location,
|
||||
config.getSafeLocationHorizontalSearchRadius(),
|
||||
config.getSafeLocationVerticalSearchRadius());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the closest possible safe location around the given location.
|
||||
*
|
||||
* @param location The target location to find
|
||||
* @param horizontalRange The radius around x,z of given location to search.
|
||||
* @param verticalRange The height of how far up and down to search.
|
||||
* @return The safe location if found, otherwise null.
|
||||
*/
|
||||
@Nullable
|
||||
public Location findSafeSpawnLocation(@NotNull Location location, int horizontalRange, int verticalRange) {
|
||||
Block safeBlock = findSafeSpawnBlock(location.getBlock(), horizontalRange, verticalRange);
|
||||
if (safeBlock == null) {
|
||||
return null;
|
||||
}
|
||||
return new Location(
|
||||
location.getWorld(),
|
||||
safeBlock.getX() + 0.5,
|
||||
safeBlock.getY(),
|
||||
safeBlock.getZ() + 0.5,
|
||||
location.getYaw(),
|
||||
location.getPitch());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the closest possible location around the given block with the configured search radius.
|
||||
*
|
||||
* @param block The target block to find
|
||||
* @return The safe block if found, otherwise null.
|
||||
*/
|
||||
@Nullable
|
||||
public Block findSafeSpawnBlock(@NotNull Block block) {
|
||||
return findSafeSpawnBlock(
|
||||
block,
|
||||
config.getSafeLocationHorizontalSearchRadius(),
|
||||
config.getSafeLocationVerticalSearchRadius());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the closest possible location around the given block.
|
||||
*
|
||||
* @param block The target block to find
|
||||
* @param horizontalRange The radius around x,z of given block to search.
|
||||
* @param verticalRange The height of how far up and down to search.
|
||||
* @return The safe block if found, otherwise null.
|
||||
*/
|
||||
@Nullable
|
||||
public Block findSafeSpawnBlock(@NotNull Block block, int horizontalRange, int verticalRange) {
|
||||
Block searchResult = searchAroundXZ(block, horizontalRange);
|
||||
if (searchResult != null) {
|
||||
return searchResult;
|
||||
}
|
||||
int maxHeight = block.getWorld().getMaxHeight();
|
||||
int minHeight = block.getWorld().getMinHeight();
|
||||
for (int i = 1; i <= verticalRange; i++) {
|
||||
if (block.getY() + i < maxHeight) {
|
||||
searchResult = searchAroundXZ(block.getRelative(0, i, 0), horizontalRange);
|
||||
if (searchResult != null) {
|
||||
return searchResult;
|
||||
}
|
||||
}
|
||||
if (block.getY() - i >= minHeight) {
|
||||
searchResult = searchAroundXZ(block.getRelative(0, -i, 0), horizontalRange);
|
||||
if (searchResult != null) {
|
||||
return searchResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search a square from n - radius to n + radius for both x and z
|
||||
*
|
||||
* @param block The block to be relative to
|
||||
* @param radius The number of blocks +/- x and z to search
|
||||
* @return The safe block, or null
|
||||
*/
|
||||
@Nullable
|
||||
private Block searchAroundXZ(Block block, int radius) {
|
||||
if (canSpawnAtBlockSafely(block)) {
|
||||
return block;
|
||||
}
|
||||
for (int r = 1; r <= radius; r++) {
|
||||
boolean radiusX = true;
|
||||
boolean incrementOffset = false;
|
||||
int offset = 0;
|
||||
int noOfIterations = r * 2 + 1;
|
||||
for (int i = 0; i < noOfIterations; i++) {
|
||||
Block searchResult = radiusX
|
||||
? searchPlusMinusPermutation(block, r, offset)
|
||||
: searchPlusMinusPermutation(block, offset, r);
|
||||
if (searchResult != null) {
|
||||
return searchResult;
|
||||
}
|
||||
if (incrementOffset) {
|
||||
offset++;
|
||||
}
|
||||
radiusX = !radiusX;
|
||||
incrementOffset = !incrementOffset;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search 4 relative blocks with the following offsets: (-x, -z) (-x, z) (x, -z) (x, z)
|
||||
*
|
||||
* @param block The block to be relative to
|
||||
* @param x Amount to offset for the x axis
|
||||
* @param z Amount to offset for the z axis
|
||||
* @return The safe block, or null
|
||||
*/
|
||||
@Nullable
|
||||
private Block searchPlusMinusPermutation(Block block, int x, int z) {
|
||||
Block relative = block.getRelative(-x, 0, -z);
|
||||
if (canSpawnAtBlockSafely(relative)) {
|
||||
return relative;
|
||||
}
|
||||
if (z != 0) {
|
||||
relative = block.getRelative(-x, 0, z);
|
||||
if (canSpawnAtBlockSafely(relative)) {
|
||||
return relative;
|
||||
}
|
||||
}
|
||||
if (x != 0) {
|
||||
relative = block.getRelative(x, 0, -z);
|
||||
if (canSpawnAtBlockSafely(relative)) {
|
||||
return relative;
|
||||
}
|
||||
if (z != 0) {
|
||||
relative = block.getRelative(x, 0, z);
|
||||
if (canSpawnAtBlockSafely(relative)) {
|
||||
return relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a portal-block next to the specified {@link Location}.
|
||||
*
|
||||
* @param location The {@link Location}
|
||||
* @return The next portal-block's {@link Location} if found, otherwise null.
|
||||
*/
|
||||
@Nullable
|
||||
public Location findPortalBlockNextTo(Location location) {
|
||||
if (location.getWorld() == null) {
|
||||
return null;
|
||||
}
|
||||
Block b = location.getWorld().getBlockAt(location);
|
||||
Location foundLocation = null;
|
||||
if (b.getType() == Material.NETHER_PORTAL) {
|
||||
return location;
|
||||
}
|
||||
if (b.getRelative(BlockFace.NORTH).getType() == Material.NETHER_PORTAL) {
|
||||
foundLocation = getCloserBlock(location, b.getRelative(BlockFace.NORTH).getLocation(), foundLocation);
|
||||
}
|
||||
if (b.getRelative(BlockFace.SOUTH).getType() == Material.NETHER_PORTAL) {
|
||||
foundLocation = getCloserBlock(location, b.getRelative(BlockFace.SOUTH).getLocation(), foundLocation);
|
||||
}
|
||||
if (b.getRelative(BlockFace.EAST).getType() == Material.NETHER_PORTAL) {
|
||||
foundLocation = getCloserBlock(location, b.getRelative(BlockFace.EAST).getLocation(), foundLocation);
|
||||
}
|
||||
if (b.getRelative(BlockFace.WEST).getType() == Material.NETHER_PORTAL) {
|
||||
foundLocation = getCloserBlock(location, b.getRelative(BlockFace.WEST).getLocation(), foundLocation);
|
||||
}
|
||||
return foundLocation;
|
||||
}
|
||||
|
||||
private Location getCloserBlock(Location source, Location blockA, Location blockB) {
|
||||
// If B wasn't given, return a.
|
||||
if (blockB == null) {
|
||||
return blockA;
|
||||
}
|
||||
// Center our calculations
|
||||
blockA.add(.5, 0, .5);
|
||||
blockB.add(.5, 0, .5);
|
||||
|
||||
// Retrieve the distance to the normalized blocks
|
||||
double testA = source.distance(blockA);
|
||||
double testB = source.distance(blockB);
|
||||
|
||||
// Compare and return
|
||||
if (testA <= testB) {
|
||||
return blockA;
|
||||
}
|
||||
return blockB;
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
|
||||
import org.mvplugins.multiverse.core.api.BlockSafety;
|
||||
import org.mvplugins.multiverse.core.destination.DestinationInstance;
|
||||
|
||||
/**
|
||||
@ -16,13 +15,13 @@ import org.mvplugins.multiverse.core.destination.DestinationInstance;
|
||||
*/
|
||||
@Service
|
||||
public class AsyncSafetyTeleporter {
|
||||
private final BlockSafety blockSafety;
|
||||
private final AdvancedBlockSafety blockSafety;
|
||||
private final TeleportQueue teleportQueue;
|
||||
private final PluginManager pluginManager;
|
||||
|
||||
@Inject
|
||||
AsyncSafetyTeleporter(
|
||||
@NotNull BlockSafety blockSafety,
|
||||
@NotNull AdvancedBlockSafety blockSafety,
|
||||
@NotNull TeleportQueue teleportQueue,
|
||||
@NotNull PluginManager pluginManager) {
|
||||
this.blockSafety = blockSafety;
|
||||
|
@ -11,7 +11,6 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.mvplugins.multiverse.core.api.BlockSafety;
|
||||
import org.mvplugins.multiverse.core.destination.DestinationInstance;
|
||||
import org.mvplugins.multiverse.core.event.MVTeleportDestinationEvent;
|
||||
import org.mvplugins.multiverse.core.utils.result.Async;
|
||||
@ -25,7 +24,7 @@ import java.util.List;
|
||||
*/
|
||||
public class AsyncSafetyTeleporterAction {
|
||||
|
||||
private final BlockSafety blockSafety;
|
||||
private final AdvancedBlockSafety blockSafety;
|
||||
private final TeleportQueue teleportQueue;
|
||||
private final PluginManager pluginManager;
|
||||
|
||||
@ -34,7 +33,7 @@ public class AsyncSafetyTeleporterAction {
|
||||
private @Nullable CommandSender teleporter = null;
|
||||
|
||||
AsyncSafetyTeleporterAction(
|
||||
@NotNull BlockSafety blockSafety,
|
||||
@NotNull AdvancedBlockSafety blockSafety,
|
||||
@NotNull TeleportQueue teleportQueue,
|
||||
@NotNull PluginManager pluginManager,
|
||||
@NotNull Either<Location, DestinationInstance<?, ?>> locationOrDestination) {
|
||||
@ -146,7 +145,7 @@ public class AsyncSafetyTeleporterAction {
|
||||
if (!this.checkSafety) {
|
||||
return Attempt.success(location);
|
||||
}
|
||||
Location safeLocation = blockSafety.getSafeLocation(location);
|
||||
Location safeLocation = blockSafety.findSafeSpawnLocation(location);
|
||||
if (safeLocation == null) {
|
||||
return Attempt.failure(TeleportFailureReason.UNSAFE_LOCATION);
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Bed;
|
||||
import org.bukkit.entity.Minecart;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
|
||||
@ -31,6 +30,7 @@ import org.mvplugins.multiverse.core.api.LocationManipulation;
|
||||
/**
|
||||
* The default-implementation of {@link BlockSafety}.
|
||||
*/
|
||||
@Deprecated
|
||||
@Service
|
||||
public class SimpleBlockSafety implements BlockSafety {
|
||||
private static final int DEFAULT_TOLERANCE = 6;
|
||||
|
@ -13,8 +13,8 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import org.mvplugins.multiverse.core.api.BlockSafety;
|
||||
import org.mvplugins.multiverse.core.api.LocationManipulation;
|
||||
import org.mvplugins.multiverse.core.teleportation.AdvancedBlockSafety;
|
||||
import org.mvplugins.multiverse.core.world.config.NullLocation;
|
||||
import org.mvplugins.multiverse.core.world.config.SpawnLocation;
|
||||
import org.mvplugins.multiverse.core.world.config.WorldConfig;
|
||||
@ -23,18 +23,16 @@ import org.mvplugins.multiverse.core.world.config.WorldConfig;
|
||||
* Extension of {@link MultiverseWorld} that represents a world that is currently loaded with bukkit world object.
|
||||
*/
|
||||
public class LoadedMultiverseWorld extends MultiverseWorld {
|
||||
private static final int SPAWN_LOCATION_SEARCH_TOLERANCE = 16;
|
||||
private static final int SPAWN_LOCATION_SEARCH_RADIUS = 16;
|
||||
|
||||
private final UUID worldUid;
|
||||
|
||||
private final BlockSafety blockSafety;
|
||||
private final AdvancedBlockSafety blockSafety;
|
||||
private final LocationManipulation locationManipulation;
|
||||
|
||||
LoadedMultiverseWorld(
|
||||
@NotNull World world,
|
||||
@NotNull WorldConfig worldConfig,
|
||||
@NotNull BlockSafety blockSafety,
|
||||
@NotNull AdvancedBlockSafety blockSafety,
|
||||
@NotNull LocationManipulation locationManipulation) {
|
||||
super(world.getName(), worldConfig);
|
||||
this.worldUid = world.getUID();
|
||||
@ -68,7 +66,7 @@ public class LoadedMultiverseWorld extends MultiverseWorld {
|
||||
Location location = world.getSpawnLocation();
|
||||
|
||||
// Verify that location was safe
|
||||
if (blockSafety.playerCanSpawnHereSafely(location)) {
|
||||
if (blockSafety.canSpawnAtLocationSafely(location)) {
|
||||
return location;
|
||||
}
|
||||
|
||||
@ -83,8 +81,7 @@ public class LoadedMultiverseWorld extends MultiverseWorld {
|
||||
// The location is not safe, so we need to find a better one.
|
||||
Logging.warning("Spawn location from world.dat file was unsafe. Adjusting...");
|
||||
Logging.warning("Original Location: " + locationManipulation.strCoordsRaw(location));
|
||||
Location newSpawn = blockSafety.getSafeLocation(location,
|
||||
SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS);
|
||||
Location newSpawn = blockSafety.findSafeSpawnLocation(location);
|
||||
// I think we could also do this, as I think this is what Notch does.
|
||||
// Not sure how it will work in the nether...
|
||||
//Location newSpawn = this.spawnLocation.getWorld().getHighestBlockAt(this.spawnLocation).getLocation();
|
||||
|
@ -27,9 +27,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
|
||||
import org.mvplugins.multiverse.core.api.BlockSafety;
|
||||
import org.mvplugins.multiverse.core.api.LocationManipulation;
|
||||
import org.mvplugins.multiverse.core.event.MVWorldDeleteEvent;
|
||||
import org.mvplugins.multiverse.core.teleportation.AdvancedBlockSafety;
|
||||
import org.mvplugins.multiverse.core.utils.message.MessageReplacement;
|
||||
import org.mvplugins.multiverse.core.utils.result.Attempt;
|
||||
import org.mvplugins.multiverse.core.utils.result.FailureReason;
|
||||
@ -76,7 +76,7 @@ public class WorldManager {
|
||||
private final GeneratorProvider generatorProvider;
|
||||
private final PlayerWorldTeleporter playerWorldActions;
|
||||
private final FilesManipulator filesManipulator;
|
||||
private final BlockSafety blockSafety;
|
||||
private final AdvancedBlockSafety blockSafety;
|
||||
private final LocationManipulation locationManipulation;
|
||||
private final PluginManager pluginManager;
|
||||
|
||||
@ -87,7 +87,7 @@ public class WorldManager {
|
||||
@NotNull GeneratorProvider generatorProvider,
|
||||
@NotNull PlayerWorldTeleporter playerWorldActions,
|
||||
@NotNull FilesManipulator filesManipulator,
|
||||
@NotNull BlockSafety blockSafety,
|
||||
@NotNull AdvancedBlockSafety blockSafety,
|
||||
@NotNull LocationManipulation locationManipulation,
|
||||
@NotNull PluginManager pluginManager) {
|
||||
this.pluginManager = pluginManager;
|
||||
|
@ -10,6 +10,7 @@ import org.mvplugins.multiverse.core.config.MVCoreConfig
|
||||
import org.mvplugins.multiverse.core.destination.Destination
|
||||
import org.mvplugins.multiverse.core.economy.MVEconomist
|
||||
import org.mvplugins.multiverse.core.listeners.*
|
||||
import org.mvplugins.multiverse.core.teleportation.AdvancedBlockSafety
|
||||
import org.mvplugins.multiverse.core.teleportation.AsyncSafetyTeleporter
|
||||
import org.mvplugins.multiverse.core.teleportation.SimpleBlockSafety
|
||||
import org.mvplugins.multiverse.core.teleportation.SimpleLocationManipulation
|
||||
@ -34,9 +35,8 @@ class InjectionTest : TestWithMockBukkit() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `BlockSafety is available as a service`() {
|
||||
assertNotNull(serviceLocator.getActiveService(BlockSafety::class.java))
|
||||
assertNotNull(serviceLocator.getActiveService(SimpleBlockSafety::class.java))
|
||||
fun `AdvancedBlockSafety is available as a service`() {
|
||||
assertNotNull(serviceLocator.getActiveService(AdvancedBlockSafety::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -7,6 +7,8 @@ teleport:
|
||||
use-finer-teleport-permissions: true
|
||||
concurrent-teleport-limit: 50
|
||||
teleport-intercept: true
|
||||
safe-location-horizontal-search-radius: 3
|
||||
safe-location-vertical-search-radius: 3
|
||||
|
||||
spawn:
|
||||
first-spawn-override: true
|
||||
|
Loading…
Reference in New Issue
Block a user