Skip to content

Commit 2df1f39

Browse files
committed
Implement rest of block safety methods
1 parent 3b9a91c commit 2df1f39

File tree

1 file changed

+116
-19
lines changed

1 file changed

+116
-19
lines changed

src/main/java/org/mvplugins/multiverse/core/teleportation/AdvancedBlockSafety.java

Lines changed: 116 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,37 @@
55
import org.bukkit.Location;
66
import org.bukkit.Material;
77
import org.bukkit.block.Block;
8+
import org.bukkit.block.data.Rail;
9+
import org.bukkit.entity.Minecart;
10+
import org.bukkit.entity.Vehicle;
811
import org.jetbrains.annotations.NotNull;
912
import org.jetbrains.annotations.Nullable;
1013
import org.jvnet.hk2.annotations.Service;
14+
import org.mvplugins.multiverse.core.api.LocationManipulation;
1115

16+
/**
17+
*
18+
*/
1219
@Service
1320
public class AdvancedBlockSafety {
1421

1522
// This will search a maximum of 7 * 6 * 7 = 294 blocks
1623
public static final int DEFAULT_HORIZONTAL_RANGE = 3;
1724
public static final int DEFAULT_VERTICAL_RANGE = 2;
1825

26+
private final LocationManipulation locationManipulation;
27+
1928
@Inject
20-
private AdvancedBlockSafety() {
29+
AdvancedBlockSafety(@NotNull LocationManipulation locationManipulation) {
30+
this.locationManipulation = locationManipulation;
2131
}
2232

2333
public boolean playerCanSpawnSafelyAt(@NotNull Location location) {
2434
return playerCanSpawnSafelyAt(location.getBlock());
2535
}
2636

2737
public boolean playerCanSpawnSafelyAt(@NotNull Block block) {
38+
Logging.finest("Checking spawn safety for location: %s, %s, %s", block.getX(), block.getY(), block.getZ());
2839
if (isUnsafeSpawnBody(block)) {
2940
// Player body will be stuck in solid
3041
Logging.finest("Unsafe location for player's body.");
@@ -42,6 +53,7 @@ public boolean playerCanSpawnSafelyAt(@NotNull Block block) {
4253
Logging.finest("Unsafe location due to invalid platform.");
4354
return false;
4455
}
56+
Logging.finest("Location is safe.");
4557
return true;
4658
}
4759

@@ -79,47 +91,88 @@ private boolean isDeepWater(@NotNull Block block) {
7991
return block.getRelative(0, -1, 0).getType() == Material.WATER;
8092
}
8193

94+
/**
95+
*
96+
*
97+
* @param location
98+
* @return The safe location, or null
99+
*/
82100
@Nullable
83101
public Location adjustSafeSpawnLocation(@NotNull Location location) {
84102
return adjustSafeSpawnLocation(location, DEFAULT_HORIZONTAL_RANGE, DEFAULT_VERTICAL_RANGE);
85103
}
86104

105+
/**
106+
*
107+
* @param location
108+
* @param horizontalRange
109+
* @param verticalRange
110+
* @return The safe location, or null
111+
*/
87112
@Nullable
88113
public Location adjustSafeSpawnLocation(@NotNull Location location, int horizontalRange, int verticalRange) {
89114
Block safeBlock = adjustSafeSpawnBlock(location.getBlock(), horizontalRange, verticalRange);
90115
if (safeBlock == null) {
91116
return null;
92117
}
93-
Location safeLocation = safeBlock.getLocation();
94-
// Adjust to center of block
95-
safeLocation.add(0.5, 0, 0.5);
96-
return safeLocation;
118+
return new Location(
119+
location.getWorld(),
120+
safeBlock.getX() + 0.5,
121+
safeBlock.getY(),
122+
safeBlock.getZ() + 0.5,
123+
location.getYaw(),
124+
location.getPitch());
97125
}
98126

127+
/**
128+
*
129+
* @param block
130+
* @return The safe block, or null
131+
*/
99132
@Nullable
100133
public Block adjustSafeSpawnBlock(@NotNull Block block) {
101134
return adjustSafeSpawnBlock(block, DEFAULT_HORIZONTAL_RANGE, DEFAULT_VERTICAL_RANGE);
102135
}
103136

137+
/**
138+
*
139+
* @param block
140+
* @param horizontalRange
141+
* @param verticalRange
142+
* @return The safe block, or null
143+
*/
104144
@Nullable
105145
public Block adjustSafeSpawnBlock(@NotNull Block block, int horizontalRange, int verticalRange) {
106146
Block searchResult = searchAroundXZ(block, horizontalRange);
107147
if (searchResult != null) {
108148
return searchResult;
109149
}
150+
int maxHeight = block.getWorld().getMaxHeight();
151+
int minHeight = block.getWorld().getMinHeight();
110152
for (int i = 1; i <= verticalRange; i++) {
111-
searchResult = searchAroundXZ(block.getRelative(0, i, 0), horizontalRange);
112-
if (searchResult != null) {
113-
return searchResult;
153+
if (block.getY() + i < maxHeight) {
154+
searchResult = searchAroundXZ(block.getRelative(0, i, 0), horizontalRange);
155+
if (searchResult != null) {
156+
return searchResult;
157+
}
114158
}
115-
searchResult = searchAroundXZ(block.getRelative(0, -i, 0), horizontalRange);
116-
if (searchResult != null) {
117-
return searchResult;
159+
if (block.getY() - i >= minHeight) {
160+
searchResult = searchAroundXZ(block.getRelative(0, -i, 0), horizontalRange);
161+
if (searchResult != null) {
162+
return searchResult;
163+
}
118164
}
119165
}
120166
return null;
121167
}
122168

169+
/**
170+
* Search a square from n - radius to n + radius for both x and z
171+
*
172+
* @param block
173+
* @param radius
174+
* @return The safe block, or null
175+
*/
123176
@Nullable
124177
private Block searchAroundXZ(Block block, int radius) {
125178
if (playerCanSpawnSafelyAt(block)) {
@@ -147,28 +200,72 @@ private Block searchAroundXZ(Block block, int radius) {
147200
return null;
148201
}
149202

203+
/**
204+
* Search 4 relative blocks with the following offsets: (-x, -z) (-x, z) (x, -z) (x, z)
205+
*
206+
* @param block The block to be relative to
207+
* @param x Amount to offset for the x axis
208+
* @param z Amount to offset for the z axis
209+
* @return The safe block, or null
210+
*/
150211
@Nullable
151212
private Block searchPlusMinusPermutation(Block block, int x, int z) {
152-
Block relative = block.getRelative(-x, 0, z);
213+
Block relative = block.getRelative(-x, 0, -z);
153214
if (playerCanSpawnSafelyAt(relative)) {
154215
return relative;
155216
}
156-
if (x != 0) {
157-
relative = block.getRelative(-x, 0, -z);
217+
if (z != 0) {
218+
relative = block.getRelative(-x, 0, z);
158219
if (playerCanSpawnSafelyAt(relative)) {
159220
return relative;
160221
}
161222
}
162-
relative = block.getRelative(x, 0, z);
163-
if (playerCanSpawnSafelyAt(relative)) {
164-
return relative;
165-
}
166-
if (z != 0) {
223+
if (x != 0) {
167224
relative = block.getRelative(x, 0, -z);
168225
if (playerCanSpawnSafelyAt(relative)) {
169226
return relative;
170227
}
228+
if (z != 0) {
229+
relative = block.getRelative(x, 0, z);
230+
if (playerCanSpawnSafelyAt(relative)) {
231+
return relative;
232+
}
233+
}
171234
}
172235
return null;
173236
}
237+
238+
public boolean isBlockAboveAir(Location location) {
239+
return location.getBlock().getRelative(0, -1, 0).getType().isAir();
240+
}
241+
242+
/**
243+
*
244+
* @param location
245+
* @return
246+
*/
247+
public boolean isEntityOnTrack(Location location) {
248+
return location.getBlock().getBlockData() instanceof Rail;
249+
}
250+
251+
/**
252+
*
253+
* @param cart
254+
* @return
255+
*/
256+
public boolean canSpawnCartSafely(Minecart cart) {
257+
if (isBlockAboveAir(cart.getLocation())) {
258+
return true;
259+
}
260+
return isEntityOnTrack(locationManipulation.getNextBlock(cart));
261+
}
262+
263+
/**
264+
*
265+
* @param vehicle
266+
* @return
267+
*/
268+
public boolean canSpawnVehicleSafely(Vehicle vehicle) {
269+
return isBlockAboveAir(vehicle.getLocation());
270+
}
174271
}

0 commit comments

Comments
 (0)