--- a/net/minecraft/world/level/EntityGetter.java
+++ b/net/minecraft/world/level/EntityGetter.java
@@ -18,6 +18,18 @@
 import net.minecraft.world.phys.shapes.VoxelShape;
 
 public interface EntityGetter {
+
+    // Paper start
+    List<Entity> getHardCollidingEntities(Entity except, AABB box, Predicate<? super Entity> predicate);
+
+    void getEntities(Entity except, AABB box, Predicate<? super Entity> predicate, List<Entity> into);
+
+    void getHardCollidingEntities(Entity except, AABB box, Predicate<? super Entity> predicate, List<Entity> into);
+
+    <T> void getEntitiesByClass(Class<? extends T> clazz, Entity except, final AABB box, List<? super T> into,
+                                Predicate<? super T> predicate);
+    // Paper end
+
     List<Entity> getEntities(@Nullable Entity except, AABB box, Predicate<? super Entity> predicate);
 
     <T extends Entity> List<T> getEntities(EntityTypeTest<Entity, T> filter, AABB box, Predicate<? super T> predicate);
@@ -37,7 +49,7 @@
             return true;
         } else {
             for(Entity entity : this.getEntities(except, shape.bounds())) {
-                if (!entity.isRemoved() && entity.blocksBuilding && (except == null || !entity.isPassengerOfSameVehicle(except)) && Shapes.joinIsNotEmpty(shape, Shapes.create(entity.getBoundingBox()), BooleanOp.AND)) {
+                if (!entity.isRemoved() && entity.blocksBuilding && (except == null || !entity.isPassengerOfSameVehicle(except)) && shape.intersects(entity.getBoundingBox())) { // Paper
                     return false;
                 }
             }
@@ -55,7 +67,7 @@
             return List.of();
         } else {
             Predicate<Entity> predicate = entity == null ? EntitySelector.CAN_BE_COLLIDED_WITH : EntitySelector.NO_SPECTATORS.and(entity::canCollideWith);
-            List<Entity> list = this.getEntities(entity, box.inflate(1.0E-7D), predicate);
+            List<Entity> list = this.getEntities(entity, box.inflate(-1.0E-7D), predicate); // Paper - needs to be negated, or else we get things we don't collide with
             if (list.isEmpty()) {
                 return List.of();
             } else {
@@ -70,8 +82,8 @@
         }
     }
 
-    @Nullable
-    default Player getNearestPlayer(double x, double y, double z, double maxDistance, @Nullable Predicate<Entity> targetPredicate) {
+    default Player findNearbyPlayer(Entity entity, double d0, @Nullable Predicate<Entity> predicate) { return this.getNearestPlayer(entity.getX(), entity.getY(), entity.getZ(), d0, predicate); } // Paper
+    @Nullable default Player getNearestPlayer(double x, double y, double z, double maxDistance, @Nullable Predicate<Entity> targetPredicate) { // Paper
         double d = -1.0D;
         Player player = null;
 
@@ -88,6 +100,28 @@
         return player;
     }
 
+    // Paper start
+    default List<org.bukkit.entity.HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, boolean notSpectator) {
+        return findNearbyBukkitPlayers(x, y, z, radius, notSpectator ? EntitySelector.NO_SPECTATORS : net.minecraft.world.entity.EntitySelector.NO_CREATIVE_OR_SPECTATOR);
+    }
+
+    default List<org.bukkit.entity.HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, @Nullable Predicate<Entity> predicate) {
+        com.google.common.collect.ImmutableList.Builder<org.bukkit.entity.HumanEntity> builder = com.google.common.collect.ImmutableList.builder();
+
+        for (Player human : this.players()) {
+            if (predicate == null || predicate.test(human)) {
+                double distanceSquared = human.distanceToSqr(x, y, z);
+
+                if (radius < 0.0D || distanceSquared < radius * radius) {
+                    builder.add(human.getBukkitEntity());
+                }
+            }
+        }
+
+        return builder.build();
+    }
+    // Paper end
+
     @Nullable
     default Player getNearestPlayer(Entity entity, double maxDistance) {
         return this.getNearestPlayer(entity.getX(), entity.getY(), entity.getZ(), maxDistance, false);
@@ -99,6 +133,27 @@
         return this.getNearestPlayer(x, y, z, maxDistance, predicate);
     }
 
+    // Paper end
+    default boolean isAffectsSpawningPlayerNearby(double d0, double d1, double d2, double d3) {
+        java.util.Iterator iterator = this.players().iterator();
+        double d4;
+        do {
+            Player entityhuman;
+            do {
+                if (!iterator.hasNext()) {
+                    return false;
+                }
+
+                entityhuman = (Player) iterator.next();
+            } while (!EntitySelector.affectsSpawning.test(entityhuman));
+
+            d4 = entityhuman.distanceToSqr(d0, d1, d2);
+        } while (d3 >= 0.0D && d4 >= d3 * d3);
+
+        return true;
+    }
+    // Paper end
+
     default boolean hasNearbyAlivePlayer(double x, double y, double z, double range) {
         for(Player player : this.players()) {
             if (EntitySelector.NO_SPECTATORS.test(player) && EntitySelector.LIVING_ENTITY_STILL_ALIVE.test(player)) {
