From 4cd00bd2211d90c38f4604afcd55457d3ded9461 Mon Sep 17 00:00:00 2001 From: Aikar Date: Wed, 4 Jul 2018 15:22:06 -0400 Subject: [PATCH] Configurable Bed Search Radius Allows you to increase how far to check for a safe place to respawn a player near their bed, allowing a better chance to respawn the player at their bed should it of became obstructed. Defaults to vanilla 1. diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java index b7e819d601..fc0455934b 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -370,4 +370,15 @@ public class PaperWorldConfig { private void scanForLegacyEnderDragon() { scanForLegacyEnderDragon = getBoolean("game-mechanics.scan-for-legacy-ender-dragon", true); } + + public int bedSearchRadius = 1; + private void bedSearchRadius() { + bedSearchRadius = getInt("bed-search-radius", 1); + if (bedSearchRadius < 1) { + bedSearchRadius = 1; + } + if (bedSearchRadius > 1) { + log("Bed Search Radius: " + bedSearchRadius); + } + } } diff --git a/src/main/java/net/minecraft/server/BlockBed.java b/src/main/java/net/minecraft/server/BlockBed.java index 43b5d00b02..b2525e2a2d 100644 --- a/src/main/java/net/minecraft/server/BlockBed.java +++ b/src/main/java/net/minecraft/server/BlockBed.java @@ -171,6 +171,10 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity { public static Optional a(EntityTypes entitytypes, IWorldReader iworldreader, BlockPosition blockposition, int i) { EnumDirection enumdirection = (EnumDirection) iworldreader.getType(blockposition).get(BlockBed.FACING); + // Paper start - configurable bed search radius + return findSafePosition(entitytypes, (World) iworldreader, enumdirection, blockposition); + } + /* int j = blockposition.getX(); int k = blockposition.getY(); int l = blockposition.getZ(); @@ -199,7 +203,103 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity { return Optional.empty(); } + */ + + private static Optional findSafePosition(EntityTypes entitytypes, World world, EnumDirection updirection, BlockPosition blockposition){ + int radius = world.paperConfig.bedSearchRadius; + double angle = Math.PI / 2; + int tmpX = (int)(updirection.getAdjacentX() * Math.cos(angle) - updirection.getAdjacentZ() * Math.sin(angle)); + int tmpZ = (int)(updirection.getAdjacentX() * Math.sin(angle) + updirection.getAdjacentZ() * Math.cos(angle)); + + EnumDirection rightDirection = EnumDirection.a(tmpX, 0, tmpZ); + EnumDirection downDirection = updirection.opposite(); + EnumDirection leftDirection = rightDirection.opposite(); + + EnumDirection[] corePositionOutDirection = new EnumDirection[6]; + corePositionOutDirection[0] = updirection; + corePositionOutDirection[1] = leftDirection; + corePositionOutDirection[2] = leftDirection; + corePositionOutDirection[3] = downDirection; + corePositionOutDirection[4] = rightDirection; + corePositionOutDirection[5] = rightDirection; + + BlockPosition[] corePosition = new BlockPosition[6]; + corePosition[0] = blockposition.add(updirection.getAdjacentX(), 0, updirection.getAdjacentZ()); + corePosition[1] = blockposition.add(leftDirection.getAdjacentX(), 0, leftDirection.getAdjacentZ()); + corePosition[2] = corePosition[1].add(downDirection.getAdjacentX(), 0, downDirection.getAdjacentZ()); + corePosition[3] = blockposition.add(2 * downDirection.getAdjacentX(), 0, 2 * downDirection.getAdjacentZ()); + corePosition[5] = blockposition.add(rightDirection.getAdjacentX(), 0, rightDirection.getAdjacentZ()); + corePosition[4] = corePosition[5].add(downDirection.getAdjacentX(), 0, downDirection.getAdjacentZ()); + + BlockPosition[] tmpPosition = new BlockPosition[8]; + EnumDirection[] tmpPositionDirection = new EnumDirection[8]; + tmpPositionDirection[0] = rightDirection; + tmpPositionDirection[1] = leftDirection; + tmpPositionDirection[2] = updirection; + tmpPositionDirection[3] = downDirection; + tmpPositionDirection[4] = leftDirection; + tmpPositionDirection[5] = rightDirection; + tmpPositionDirection[6] = downDirection; + tmpPositionDirection[7] = updirection; + + BlockPosition pos; + Optional vector; + for (int r = 1; r <= radius; r++) { + int h = 0; + while (h <= 1) { + int numIterated = 0; + for (int index = (int)(Math.random() * corePosition.length); numIterated < corePosition.length; index = (index+1) % corePosition.length) { + numIterated++; + + pos = corePosition[index].add(0, h, 0); + vector = isSafeRespawn(entitytypes, world, pos); + if (vector.isPresent()) { + return vector; + } + } + tmpPosition[0] = corePosition[0].add(0, h, 0); + tmpPosition[1] = corePosition[0].add(0, h, 0); + tmpPosition[2] = corePosition[1].add(0, h, 0); + tmpPosition[3] = corePosition[2].add(0, h, 0); + tmpPosition[4] = corePosition[3].add(0, h, 0); + tmpPosition[5] = corePosition[3].add(0, h, 0); + tmpPosition[6] = corePosition[4].add(0, h, 0); + tmpPosition[7] = corePosition[5].add(0, h, 0); + for (int rr = 1; rr <= r; rr++){ + numIterated = 0; + for (int index = (int)(Math.random() * tmpPosition.length); numIterated < tmpPosition.length; index = (index+1) % tmpPosition.length) { + numIterated++; + tmpPosition[index] = tmpPosition[index].add(tmpPositionDirection[index].getAdjacentX(), 0, tmpPositionDirection[index].getAdjacentZ()); + pos = tmpPosition[index]; + + vector = isSafeRespawn(entitytypes, world, pos); + if (vector.isPresent()) { + return vector; + } + } + } + switch (h) { + case -1: + h = 1; + break; + case 0: + h = -1; + break; + case 1: + h = Integer.MAX_VALUE; + break; + } + } + for (int index = 0; index < corePosition.length; index++) { + EnumDirection tmp = corePositionOutDirection[index]; + corePosition[index] = corePosition[index].add(tmp.getAdjacentX(), 0, tmp.getAdjacentZ()); + } + } + return Optional.empty(); + } + // Paper end + protected static Optional isSafeRespawn(EntityTypes entityTypes, IWorldReader iworldreader, BlockPosition blockPosition) { return a(entityTypes, iworldreader, blockPosition); } // Paper -- obfhelper protected static Optional a(EntityTypes entitytypes, IWorldReader iworldreader, BlockPosition blockposition) { VoxelShape voxelshape = iworldreader.getType(blockposition).getCollisionShape(iworldreader, blockposition); -- 2.22.0