aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches/0280-Configurable-Bed-Search-Radius.patch
blob: 41e4e778786ca947ffde0fef0ae9670a885bb6a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
From fbc5aa049c925955355972e08ce896e10c5b4d3e 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 aa2be2ed..f5b2e88f 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -452,4 +452,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 06f62700..0ab2112c 100644
--- a/src/main/java/net/minecraft/server/BlockBed.java
+++ b/src/main/java/net/minecraft/server/BlockBed.java
@@ -187,6 +187,10 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity {
     @Nullable
     public static BlockPosition a(IBlockAccess iblockaccess, BlockPosition blockposition, int i) {
         EnumDirection enumdirection = (EnumDirection) iblockaccess.getType(blockposition).get(BlockBed.FACING);
+        // Paper start - replace whole method
+        return findSafePosition((World)iblockaccess, enumdirection, blockposition);
+    }
+        /* // Paper comment out
         int j = blockposition.getX();
         int k = blockposition.getY();
         int l = blockposition.getZ();
@@ -212,9 +216,106 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity {
             }
         }
 
+        return null;
+    }*/ // Paper comment out
+
+    private static BlockPosition findSafePosition(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;
+        boolean foundPosition;
+        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);
+                    foundPosition = isSafeRespawn(world, pos);
+                    if (foundPosition) {
+                        return pos;
+                    }
+                }
+                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];
+
+                        foundPosition = isSafeRespawn(world, pos);
+                        if (foundPosition) {
+                            return pos;
+                        }
+                    }
+                }
+                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 null;
     }
+    // Paper end
 
+    protected static boolean isSafeRespawn(IBlockAccess iblockaccess, BlockPosition blockposition) { // Paper - OBFHELPER + behavior improvement
+        return a(iblockaccess, blockposition) && iblockaccess.getType(blockposition.down()).getMaterial().isBuildable(); // Paper - ensure solid block
+    }
     protected static boolean a(IBlockAccess iblockaccess, BlockPosition blockposition) {
         return iblockaccess.getType(blockposition.down()).q() && !iblockaccess.getType(blockposition).getMaterial().isBuildable() && !iblockaccess.getType(blockposition.up()).getMaterial().isBuildable();
     }
-- 
2.19.0