/
Utilities.java
69 lines (57 loc) · 2.58 KB
/
Utilities.java
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
package net.aufdemrand.denizen.nms.util;
import net.aufdemrand.denizen.nms.NMSHandler;
import net.aufdemrand.denizen.nms.interfaces.BlockHelper;
import org.bukkit.Location;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Utilities {
private static final Random random = new Random();
/**
* Gets a Location within a range that an entity can walk in.
*
* @param location the Location to check with
* @param range the range around the Location
* @return a random Location within range, or null if no Location within range is safe
*/
public static Location getWalkableLocationNear(Location location, int range) {
List<Location> locations = new ArrayList<>();
location = location.getBlock().getLocation();
// Loop through each location within the range
for (double x = -(range); x <= range; x++) {
for (double y = -(range); y <= range; y++) {
for (double z = -(range); z <= range; z++) {
// Add each block location within range
Location loc = location.clone().add(x, y, z);
if (checkLocation(location, loc, range) && isWalkable(loc)) {
locations.add(loc);
}
}
}
}
// No safe Locations found
if (locations.isEmpty()) {
return null;
}
// Return a random Location from the list
return locations.get(random.nextInt(locations.size()));
}
public static boolean isWalkable(Location location) {
BlockHelper blockHelper = NMSHandler.getInstance().getBlockHelper();
return !blockHelper.isSafeBlock(location.clone().subtract(0, 1, 0).getBlock().getType())
&& blockHelper.isSafeBlock(location.getBlock().getType())
&& blockHelper.isSafeBlock(location.clone().add(0, 1, 0).getBlock().getType());
}
/**
* Checks entity's location against a Location (with leeway). Should be faster than
* bukkit's built in Location.distance(Location) since there's no sqrt math.
*
* @return true if within the specified location, false otherwise.
*/
public static boolean checkLocation(Location baseLocation, Location theLocation, double theLeeway) {
if (!baseLocation.getWorld().getName().equals(theLocation.getWorld().getName())) {
return false;
}
return baseLocation.distanceSquared(theLocation) < theLeeway * theLeeway;
}
}