Paper/removed/1.16/0238-Configurable-Bed-Search-Radius.patch
Daniel Ennis c97ce029e9
1.16.2 Release (#4123)
PaperMC believes that 1.16.2 is now ready for general release as we fixed the main issue plagueing the 1.16.x release, the MapLike data conversion issues.

Until now, it was not safe for a server to convert a world to 1.16.2 without data conversion issues around villages and potentially other things. If you did, those MapLike errors meant something went wrong.

This is now resolved.

Big thanks to all those that helped, notably @BillyGalbreath and @Proximyst who did large parts of the update process with me.

Please as always, backup your worlds and test before updating to 1.16.2!

If you update to 1.16.2, there is no going back to an older build than this.

---------------------------------

Co-authored-by: William Blake Galbreath <Blake.Galbreath@GMail.com>
Co-authored-by: Mariell Hoversholm <proximyst@proximyst.com>
Co-authored-by: krolik-exe <69214078+krolik-exe@users.noreply.github.com>
Co-authored-by: BillyGalbreath <BillyGalbreath@users.noreply.github.com>
Co-authored-by: stonar96 <minecraft.stonar96@gmail.com>
Co-authored-by: Shane Freeder <theboyetronic@gmail.com>
Co-authored-by: Jason <jasonpenilla2@me.com>
Co-authored-by: kashike <kashike@vq.lc>
Co-authored-by: Aurora <21148213+aurorasmiles@users.noreply.github.com>
Co-authored-by: KennyTV <kennytv@t-online.de>
Co-authored-by: commandblockguy <commandblockguy1@gmail.com>
Co-authored-by: DigitalRegent <misterwener@gmail.com>
Co-authored-by: ishland <ishlandmc@yeah.net>
2020-08-24 22:40:19 -04:00

160 lines
8.8 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
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 6352051ab937d4d365e823a7112e76dc3ec34225..d6a3d882e375ac5a2b6ec8920532db615f4fe4ef 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -372,4 +372,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 7604d79468ce8d7d1a4f45872a5db0c700419029..e7bd9061cceba284443b75cc5506e1b9f2ef42e8 100644
--- a/src/main/java/net/minecraft/server/BlockBed.java
+++ b/src/main/java/net/minecraft/server/BlockBed.java
@@ -199,6 +199,8 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity {
public static Optional<Vec3D> a(EntityTypes<?> entitytypes, IWorldReader iworldreader, BlockPosition blockposition, int i) {
EnumDirection enumdirection = (EnumDirection) iworldreader.getType(blockposition).get(BlockBed.FACING);
+ // Paper start - configurable bed search radius
+ if (entitytypes == EntityTypes.PLAYER) return findSafePosition(entitytypes, (World) iworldreader, enumdirection, blockposition);
int j = blockposition.getX();
int k = blockposition.getY();
int l = blockposition.getZ();
@@ -228,7 +230,104 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity {
return Optional.empty();
}
- public static Optional<Vec3D> a(EntityTypes<?> entitytypes, IWorldReader iworldreader, BlockPosition blockposition) {
+ private static Optional<Vec3D> 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<Vec3D> 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, 0);
+ 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, 0);
+ if (vector.isPresent()) {
+ return vector;
+ }
+ }
+ }
+ switch (h) {
+ case 0:
+ h = -1;
+ break;
+ case -1:
+ h = -2;
+ break;
+ case -2:
+ 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
+
+ // Paper start -- add maxBelow param
+ public static Optional<Vec3D> a(EntityTypes<?> entitytypes, IWorldReader iworldreader, BlockPosition blockposition) { return isSafeRespawn(entitytypes, iworldreader, blockposition, 2); }
+ public static Optional<Vec3D> isSafeRespawn(EntityTypes<?> entitytypes, IWorldReader iworldreader, BlockPosition blockposition, int maxBelow) {
+ // Paper end
VoxelShape voxelshape = iworldreader.getType(blockposition).getCollisionShape(iworldreader, blockposition);
if (voxelshape.c(EnumDirection.EnumAxis.Y) > 0.4375D) {
@@ -236,7 +335,7 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity {
} else {
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = blockposition.i();
- while (blockposition_mutableblockposition.getY() >= 0 && blockposition.getY() - blockposition_mutableblockposition.getY() <= 2 && iworldreader.getType(blockposition_mutableblockposition).getCollisionShape(iworldreader, blockposition_mutableblockposition).isEmpty()) {
+ while (blockposition_mutableblockposition.getY() >= 0 && blockposition.getY() - blockposition_mutableblockposition.getY() <= maxBelow && iworldreader.getType(blockposition_mutableblockposition).getCollisionShape(iworldreader, blockposition_mutableblockposition).isEmpty()) { // Paper -- configurable max distance to search below
blockposition_mutableblockposition.c(EnumDirection.DOWN);
}