36f34f01c0
Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: da9ef3c5 #496: Add methods to get/set ItemStacks in EquipmentSlots 3abebc9f #492: Let Tameable extend Animals rather than Entity 941111a0 #495: Expose ItemStack and hand used in PlayerShearEntityEvent 4fe19cae #494: InventoryView - Add missing Brewing FUEL_TIME CraftBukkit Changes: 933e9094 #664: Add methods to get/set ItemStacks in EquipmentSlots 18722312 #662: Expose ItemStack and hand used in PlayerShearEntityEvent
160 lines
8.8 KiB
Diff
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 cea15d50ed89430ee8d8cff9de21e1fc7982e1d8..387e0dcb9f01ad947daaa19211331a96742ce004 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
@@ -377,4 +377,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 7947563426f7f1cc9364d7b6f71256bf3beea463..e0bc6080ef29258473ec3ef7ffa7c246f08ac146 100644
|
|
--- a/src/main/java/net/minecraft/server/BlockBed.java
|
|
+++ b/src/main/java/net/minecraft/server/BlockBed.java
|
|
@@ -196,6 +196,9 @@ 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();
|
|
@@ -225,7 +228,104 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity {
|
|
return Optional.empty();
|
|
}
|
|
|
|
- protected 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
|
|
+ protected static Optional<Vec3D> a(EntityTypes<?> entitytypes, IWorldReader iworldreader, BlockPosition blockposition) { return isSafeRespawn(entitytypes, iworldreader, blockposition, 2); }
|
|
+ protected 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) {
|
|
@@ -233,7 +333,7 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity {
|
|
} else {
|
|
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(blockposition);
|
|
|
|
- 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);
|
|
}
|
|
|