Paper/Spigot-Server-Patches/0241-Configurable-Bed-Search-Radius.patch
Aikar 57dd397155
Updated Upstream (Bukkit/CraftBukkit)
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:
b999860d SPIGOT-2304: Add LootGenerateEvent

CraftBukkit Changes:
77fd87e4 SPIGOT-2304: Implement LootGenerateEvent
a1a705ee SPIGOT-5566: Doused campfires & fires should call EntityChangeBlockEvent
41712edd SPIGOT-5707: PersistentDataHolder not Persistent on API dropped Item
2020-05-01 18:03:57 -04:00

167 lines
8.7 KiB
Diff

From 8484c9a9399fea29f53b0e0255d6f584cdce5543 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 cea15d50ed..387e0dcb9f 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 7947563426..74e915c21e 100644
--- a/src/main/java/net/minecraft/server/BlockBed.java
+++ b/src/main/java/net/minecraft/server/BlockBed.java
@@ -196,6 +196,10 @@ 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
+ return findSafePosition(entitytypes, (World) iworldreader, enumdirection, blockposition);
+ }
+/*
int j = blockposition.getX();
int k = blockposition.getY();
int l = blockposition.getZ();
@@ -224,8 +228,106 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity {
return Optional.empty();
}
+ */
+
+ 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
- protected static Optional<Vec3D> a(EntityTypes<?> entitytypes, IWorldReader iworldreader, BlockPosition blockposition) {
+ // 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 +335,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);
}
--
2.26.2