From 2715be9fef9f1c9b4196b79fa83fc302e68ea945 Mon Sep 17 00:00:00 2001
From: Omer Uddin <kickash32@gmail.com>
Date: Sat, 22 Jun 2019 13:59:47 -0400
Subject: [PATCH] Rework bed dismount mechanics (#2145)

Fixes #1726
---
 .../0249-Configurable-Bed-Search-Radius.patch | 164 +++++++++++-------
 1 file changed, 106 insertions(+), 58 deletions(-)

diff --git a/Spigot-Server-Patches/0249-Configurable-Bed-Search-Radius.patch b/Spigot-Server-Patches/0249-Configurable-Bed-Search-Radius.patch
index d2c9ee4d4..a4830277e 100644
--- a/Spigot-Server-Patches/0249-Configurable-Bed-Search-Radius.patch
+++ b/Spigot-Server-Patches/0249-Configurable-Bed-Search-Radius.patch
@@ -1,4 +1,4 @@
-From 474a91281a23a7277d78441d0f97139feba15b0c Mon Sep 17 00:00:00 2001
+From 4817baa2bdd791a7c813118c88a33b95011ef849 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
@@ -10,7 +10,7 @@ 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 3294fbbeaf..83e54cb904 100644
+index 3294fbbe..83e54cb9 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 @@ -375,4 +375,15 @@ public class PaperWorldConfig {
@@ -30,76 +30,124 @@ index 3294fbbeaf..83e54cb904 100644
 +    }
  }
 diff --git a/src/main/java/net/minecraft/server/BlockBed.java b/src/main/java/net/minecraft/server/BlockBed.java
-index c49eb0ecb3..034226d0b3 100644
+index c49eb0ec..70222713 100644
 --- a/src/main/java/net/minecraft/server/BlockBed.java
 +++ b/src/main/java/net/minecraft/server/BlockBed.java
-@@ -171,6 +171,58 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity {
+@@ -171,6 +171,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 -  configurable bed search radius
-+        World world = (World) iworldreader;
-+        int radius = world.paperConfig.bedSearchRadius;
-+        if (radius > 0) {
-+            for (int r = 1; r <= radius; r++) {
-+                int x = -r;
-+                int z = r;
-+
-+                // Iterates the edge of half of the box; then negates for other half.
-+                while (x <= r && z > -r) {
-+                    for (int y = -1; y <= 1; y++) {
-+                        BlockPosition pos = blockposition.add(x, y, z);
-+                        Optional<Vec3D> vector;
-+                        vector = isSafeRespawn(entitytypes, world, pos);
-+                        if (vector.isPresent()) {
-+                            if (i-- <= 0) {
-+                                return vector;
-+                            }
-+                        }
-+                        pos = blockposition.add(-x, y, -z);
-+                        vector = isSafeRespawn(entitytypes, world, pos);
-+                        if (vector.isPresent()) {
-+                            if (i-- <= 0) {
-+                                return vector;
-+                            }
-+                        }
-+
-+                        vector = isSafeRespawn(entitytypes, world, pos);
-+                        if (vector.isPresent()) {
-+                            if (i-- <= 0) {
-+                                return vector;
-+                            }
-+                        }
-+
-+                        vector = isSafeRespawn(entitytypes, world, pos);
-+                        if (vector.isPresent()) {
-+                            if (i-- <= 0) {
-+                                return vector;
-+                            }
-+                        }
-+                    }
-+                    if (x < r) {
-+                        x++;
-+                    } else {
-+                        z--;
-+                    }
-+                }
-+            }
-+
-+            return Optional.empty();
-+        }
-+        // Paper end
++    // 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();
-@@ -200,6 +252,7 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity {
+@@ -199,7 +203,103 @@ 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);
++                    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<Vec3D> isSafeRespawn(EntityTypes<?> entityTypes, IWorldReader iworldreader, BlockPosition blockPosition) { return a(entityTypes, iworldreader, blockPosition); } // Paper -- obfhelper
      protected static Optional<Vec3D> a(EntityTypes<?> entitytypes, IWorldReader iworldreader, BlockPosition blockposition) {
          VoxelShape voxelshape = iworldreader.getType(blockposition).getCollisionShape(iworldreader, blockposition);
  
 -- 
-2.21.0
+2.22.0