From 7991f82af6e972ee2ff68cb2c3d777f5226999e8 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 30 Apr 2018 17:55:28 -0400
Subject: [PATCH] Additional world.getNearbyEntities API's

Provides more methods to get nearby entities, and filter by types and predicates

diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
index 4e07af2e..49d2cc45 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -2,11 +2,14 @@ package org.bukkit;
 
 import java.io.File;
 import org.bukkit.generator.ChunkGenerator;
+
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.function.Predicate;
 
 import org.bukkit.block.Biome;
 import org.bukkit.block.Block;
@@ -435,6 +438,205 @@ public interface World extends PluginMessageRecipient, Metadatable {
      */
     public Collection<Entity> getEntitiesByClasses(Class<?>... classes);
 
+    // Paper start
+    /**
+     * Gets nearby players within the specified radius (bounding box)
+     * @param loc Center location
+     * @param radius X Radius
+     */
+    public default Collection<LivingEntity> getNearbyLivingEntities(Location loc, double radius) {
+        return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, radius, radius, radius);
+    }
+
+    /**
+     * Gets nearby players within the specified radius (bounding box)
+     * @param loc Center location
+     * @param xzRadius X/Z Radius
+     * @param yRadius Y Radius
+     */
+    public default Collection<LivingEntity> getNearbyLivingEntities(Location loc, double xzRadius, double yRadius) {
+        return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, xzRadius, yRadius, xzRadius);
+    }
+
+    /**
+     * Gets nearby players within the specified radius (bounding box)
+     * @param loc Center location
+     * @param xRadius X Radius
+     * @param yRadius Y Radius
+     * @param zRadius Z radius
+     */
+    public default Collection<LivingEntity> getNearbyLivingEntities(Location loc, double xRadius, double yRadius, double zRadius) {
+        return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, xRadius, yRadius, zRadius);
+    }
+
+    /**
+     * Gets nearby players within the specified radius (bounding box)
+     * @param loc Center location
+     * @param radius X Radius
+     */
+    public default Collection<LivingEntity> getNearbyLivingEntities(Location loc, double radius, Predicate<LivingEntity> predicate) {
+        return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, radius, radius, radius, predicate);
+    }
+
+    /**
+     * Gets nearby players within the specified radius (bounding box)
+     * @param loc Center location
+     * @param xzRadius X/Z Radius
+     * @param yRadius Y Radius
+     */
+    public default Collection<LivingEntity> getNearbyLivingEntities(Location loc, double xzRadius, double yRadius, Predicate<LivingEntity> predicate) {
+        return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, xzRadius, yRadius, xzRadius, predicate);
+    }
+
+    /**
+     * Gets nearby players within the specified radius (bounding box)
+     * @param loc Center location
+     * @param xRadius X Radius
+     * @param yRadius Y Radius
+     * @param zRadius Z radius
+     */
+    public default Collection<LivingEntity> getNearbyLivingEntities(Location loc, double xRadius, double yRadius, double zRadius, Predicate<LivingEntity> predicate) {
+        return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, xRadius, yRadius, zRadius, predicate);
+    }
+
+    /**
+     * Gets nearby players within the specified radius (bounding box)
+     * @param loc Center location
+     * @param radius X/Y/Z Radius
+     */
+    public default Collection<Player> getNearbyPlayers(Location loc, double radius) {
+        return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, radius, radius, radius);
+    }
+
+    /**
+     * Gets nearby players within the specified radius (bounding box)
+     * @param loc Center location
+     * @param xzRadius X/Z Radius
+     * @param yRadius Y Radius
+     */
+    public default Collection<Player> getNearbyPlayers(Location loc, double xzRadius, double yRadius) {
+        return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, xzRadius, yRadius, xzRadius);
+    }
+
+    /**
+     * Gets nearby players within the specified radius (bounding box)
+     * @param loc Center location
+     * @param xRadius X Radius
+     * @param yRadius Y Radius
+     * @param zRadius Z Radius
+     */
+    public default Collection<Player> getNearbyPlayers(Location loc, double xRadius, double yRadius, double zRadius) {
+        return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, xRadius, yRadius, zRadius);
+    }
+
+    /**
+     * Gets nearby players within the specified radius (bounding box)
+     * @param loc Center location
+     * @param radius X/Y/Z Radius
+     */
+    public default Collection<Player> getNearbyPlayers(Location loc, double radius, Predicate<Player> predicate) {
+        return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, radius, radius, radius, predicate);
+    }
+
+    /**
+     * Gets nearby players within the specified radius (bounding box)
+     * @param loc Center location
+     * @param xzRadius X/Z Radius
+     * @param yRadius Y Radius
+     */
+    public default Collection<Player> getNearbyPlayers(Location loc, double xzRadius, double yRadius, Predicate<Player> predicate) {
+        return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, xzRadius, yRadius, xzRadius, predicate);
+    }
+
+    /**
+     * Gets nearby players within the specified radius (bounding box)
+     * @param loc Center location
+     * @param xRadius X Radius
+     * @param yRadius Y Radius
+     * @param zRadius Z Radius
+     */
+    public default Collection<Player> getNearbyPlayers(Location loc, double xRadius, double yRadius, double zRadius, Predicate<Player> predicate) {
+        return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, xRadius, yRadius, zRadius, predicate);
+    }
+
+    /**
+     * Gets all nearby entities of the specified type, within the specified radius (bounding box)
+     * @param clazz Type to filter by
+     * @param loc Center location
+     * @param radius X/Y/Z radius to search within
+     */
+    public default <T extends Entity> Collection<T> getNearbyEntitiesByType(Class<? extends T> clazz, Location loc, double radius) {
+        return getNearbyEntitiesByType(clazz, loc, radius, radius, radius, null);
+    }
+
+    /**
+     * Gets all nearby entities of the specified type, within the specified radius, with x and x radius matching (bounding box)
+     * @param clazz Type to filter by
+     * @param loc Center location
+     * @param xzRadius X/Z radius to search within
+     * @param yRadius Y radius to search within
+     */
+    public default <T extends Entity> Collection<T> getNearbyEntitiesByType(Class<? extends T> clazz, Location loc, double xzRadius, double yRadius) {
+        return getNearbyEntitiesByType(clazz, loc, xzRadius, yRadius, xzRadius, null);
+    }
+
+    /**
+     * Gets all nearby entities of the specified type, within the specified radius (bounding box)
+     * @param clazz Type to filter by
+     * @param loc Center location
+     * @param xRadius X Radius
+     * @param yRadius Y Radius
+     * @param zRadius Z Radius
+     */
+    public default <T extends Entity> Collection<T> getNearbyEntitiesByType(Class<? extends T> clazz, Location loc, double xRadius, double yRadius, double zRadius) {
+        return getNearbyEntitiesByType(clazz, loc, xRadius, yRadius, zRadius, null);
+    }
+
+    /**
+     * Gets all nearby entities of the specified type, within the specified radius (bounding box)
+     * @param clazz Type to filter by
+     * @param loc Center location
+     * @param radius X/Y/Z radius to search within
+     */
+    public default <T extends Entity> Collection<T> getNearbyEntitiesByType(Class<? extends T> clazz, Location loc, double radius, Predicate<T> predicate) {
+        return getNearbyEntitiesByType(clazz, loc, radius, radius, radius, predicate);
+    }
+
+    /**
+     * Gets all nearby entities of the specified type, within the specified radius, with x and x radius matching (bounding box)
+     * @param clazz Type to filter by
+     * @param loc Center location
+     * @param xzRadius X/Z radius to search within
+     * @param yRadius Y radius to search within
+     */
+    public default <T extends Entity> Collection<T> getNearbyEntitiesByType(Class<? extends T> clazz, Location loc, double xzRadius, double yRadius, Predicate<T> predicate) {
+        return getNearbyEntitiesByType(clazz, loc, xzRadius, yRadius, xzRadius, predicate);
+    }
+
+     /**
+     * Gets all nearby entities of the specified type, within the specified radius (bounding box)
+     * @param clazz Type to filter by
+     * @param loc Center location
+     * @param xRadius X Radius
+     * @param yRadius Y Radius
+     * @param zRadius Z Radius
+     */
+    public default <T extends Entity> Collection<T> getNearbyEntitiesByType(Class<? extends Entity> clazz, Location loc, double xRadius, double yRadius, double zRadius, Predicate<T> predicate) {
+        if (clazz == null) {
+            clazz = Entity.class;
+        }
+        List<T> nearby = new ArrayList<>();
+        for (Entity bukkitEntity : getNearbyEntities(loc, xRadius, yRadius, zRadius)) {
+            //noinspection unchecked
+            if (clazz.isAssignableFrom(bukkitEntity.getClass()) && (predicate == null || predicate.test((T) bukkitEntity))) {
+                //noinspection unchecked
+                nearby.add((T) bukkitEntity);
+            }
+        }
+        return nearby;
+    }
+    // Paper end
+
     /**
      * Get a list of all players in this World
      *
-- 
2.18.0