mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-29 12:27:59 +01:00
Avoid a cubed max search distance for POIs (#8576)
The max search distance used to get the closest Poi data on X/Z axis is cubed instead of squared (one time in the parameter and another time in the function) for almost all search. Generally this has been hidden by another check that already does a pre distance check between the poi pos and the source pos for individual component but the issue still happens for diagonal distance search. Discovered by Samsuik
This commit is contained in:
parent
b36d2af7d5
commit
944be7b031
@ -122,11 +122,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ final Predicate<BlockPos> positionPredicate,
|
||||
+ final BlockPos sourcePosition,
|
||||
+ final int range, // distance on x y z axis
|
||||
+ final double maxDistance,
|
||||
+ final double maxDistanceSquared,
|
||||
+ final PoiManager.Occupancy occupancy,
|
||||
+ final boolean load) {
|
||||
+ final PoiRecord ret = findClosestPoiDataRecord(
|
||||
+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistance, occupancy, load
|
||||
+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load
|
||||
+ );
|
||||
+
|
||||
+ return ret == null ? null : ret.getPos();
|
||||
@ -140,11 +140,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ final Predicate<BlockPos> positionPredicate,
|
||||
+ final BlockPos sourcePosition,
|
||||
+ final int range, // distance on x y z axis
|
||||
+ final double maxDistance,
|
||||
+ final double maxDistanceSquared,
|
||||
+ final PoiManager.Occupancy occupancy,
|
||||
+ final boolean load) {
|
||||
+ final PoiRecord ret = findClosestPoiDataRecord(
|
||||
+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistance, occupancy, load
|
||||
+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load
|
||||
+ );
|
||||
+
|
||||
+ return ret == null ? null : Pair.of(ret.getPoiType(), ret.getPos());
|
||||
@ -158,7 +158,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ final Predicate<BlockPos> positionPredicate,
|
||||
+ final BlockPos sourcePosition,
|
||||
+ final int range, // distance on x y z axis
|
||||
+ final double maxDistance,
|
||||
+ final double maxDistanceSquared,
|
||||
+ final PoiManager.Occupancy occupancy,
|
||||
+ final boolean load,
|
||||
+ final Set<BlockPos> ret) {
|
||||
@ -173,7 +173,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+
|
||||
+ final List<PoiRecord> toConvert = new ArrayList<>();
|
||||
+ findClosestPoiDataRecords(
|
||||
+ poiStorage, villagePlaceType, newPredicate, sourcePosition, range, maxDistance, occupancy, load, toConvert
|
||||
+ poiStorage, villagePlaceType, newPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load, toConvert
|
||||
+ );
|
||||
+
|
||||
+ for (final PoiRecord record : toConvert) {
|
||||
@ -189,12 +189,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ final Predicate<BlockPos> positionPredicate,
|
||||
+ final BlockPos sourcePosition,
|
||||
+ final int range, // distance on x y z axis
|
||||
+ final double maxDistance,
|
||||
+ final double maxDistanceSquared,
|
||||
+ final PoiManager.Occupancy occupancy,
|
||||
+ final boolean load) {
|
||||
+ final List<PoiRecord> ret = new ArrayList<>();
|
||||
+ findClosestPoiDataRecords(
|
||||
+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistance, occupancy, load, ret
|
||||
+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load, ret
|
||||
+ );
|
||||
+ return ret.isEmpty() ? null : ret.get(0);
|
||||
+ }
|
||||
@ -207,12 +207,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ final BiPredicate<Holder<PoiType>, BlockPos> predicate,
|
||||
+ final BlockPos sourcePosition,
|
||||
+ final int range, // distance on x y z axis
|
||||
+ final double maxDistance,
|
||||
+ final double maxDistanceSquared,
|
||||
+ final PoiManager.Occupancy occupancy,
|
||||
+ final boolean load) {
|
||||
+ final List<PoiRecord> ret = new ArrayList<>();
|
||||
+ findClosestPoiDataRecords(
|
||||
+ poiStorage, villagePlaceType, predicate, sourcePosition, range, maxDistance, occupancy, load, ret
|
||||
+ poiStorage, villagePlaceType, predicate, sourcePosition, range, maxDistanceSquared, occupancy, load, ret
|
||||
+ );
|
||||
+ return ret.isEmpty() ? null : ret.get(0);
|
||||
+ }
|
||||
@ -225,12 +225,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ final Predicate<BlockPos> positionPredicate,
|
||||
+ final BlockPos sourcePosition,
|
||||
+ final int range, // distance on x y z axis
|
||||
+ final double maxDistance,
|
||||
+ final double maxDistanceSquared,
|
||||
+ final PoiManager.Occupancy occupancy,
|
||||
+ final boolean load,
|
||||
+ final List<PoiRecord> ret) {
|
||||
+ final BiPredicate<Holder<PoiType>, BlockPos> predicate = positionPredicate != null ? (type, pos) -> positionPredicate.test(pos) : null;
|
||||
+ findClosestPoiDataRecords(poiStorage, villagePlaceType, predicate, sourcePosition, range, maxDistance, occupancy, load, ret);
|
||||
+ findClosestPoiDataRecords(poiStorage, villagePlaceType, predicate, sourcePosition, range, maxDistanceSquared, occupancy, load, ret);
|
||||
+ }
|
||||
+
|
||||
+ public static void findClosestPoiDataRecords(final PoiManager poiStorage,
|
||||
@ -239,14 +239,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ final BiPredicate<Holder<PoiType>, BlockPos> predicate,
|
||||
+ final BlockPos sourcePosition,
|
||||
+ final int range, // distance on x y z axis
|
||||
+ final double maxDistance,
|
||||
+ final double maxDistanceSquared,
|
||||
+ final PoiManager.Occupancy occupancy,
|
||||
+ final boolean load,
|
||||
+ final List<PoiRecord> ret) {
|
||||
+ final Predicate<? super PoiRecord> occupancyFilter = occupancy.getTest();
|
||||
+
|
||||
+ final List<PoiRecord> closestRecords = new ArrayList<>();
|
||||
+ double closestDistanceSquared = maxDistance * maxDistance;
|
||||
+ double closestDistanceSquared = maxDistanceSquared;
|
||||
+
|
||||
+ final int lowerX = Mth.floor(sourcePosition.getX() - range) >> 4;
|
||||
+ final int lowerY = WorldUtil.getMinSection(poiStorage.world);
|
||||
@ -413,11 +413,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ final Predicate<BlockPos> positionPredicate,
|
||||
+ final BlockPos sourcePosition,
|
||||
+ final int range, // distance on x y z axis
|
||||
+ final double maxDistance,
|
||||
+ final double maxDistanceSquared,
|
||||
+ final PoiManager.Occupancy occupancy,
|
||||
+ final boolean load) {
|
||||
+ final PoiRecord ret = findNearestPoiRecord(
|
||||
+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistance, occupancy, load
|
||||
+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load
|
||||
+ );
|
||||
+ return ret == null ? null : ret.getPos();
|
||||
+ }
|
||||
@ -429,7 +429,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ final Predicate<BlockPos> positionPredicate,
|
||||
+ final BlockPos sourcePosition,
|
||||
+ final int range, // distance on x y z axis
|
||||
+ final double maxDistance,
|
||||
+ final double maxDistanceSquared,
|
||||
+ final PoiManager.Occupancy occupancy,
|
||||
+ final boolean load,
|
||||
+ final int max,
|
||||
@ -445,7 +445,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+
|
||||
+ final List<PoiRecord> toConvert = new ArrayList<>();
|
||||
+ findNearestPoiRecords(
|
||||
+ poiStorage, villagePlaceType, newPredicate, sourcePosition, range, maxDistance, occupancy, load, max, toConvert
|
||||
+ poiStorage, villagePlaceType, newPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load, max, toConvert
|
||||
+ );
|
||||
+
|
||||
+ for (final PoiRecord record : toConvert) {
|
||||
@ -460,12 +460,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ final Predicate<BlockPos> positionPredicate,
|
||||
+ final BlockPos sourcePosition,
|
||||
+ final int range, // distance on x y z axis
|
||||
+ final double maxDistance,
|
||||
+ final double maxDistanceSquared,
|
||||
+ final PoiManager.Occupancy occupancy,
|
||||
+ final boolean load) {
|
||||
+ final List<PoiRecord> ret = new ArrayList<>();
|
||||
+ findNearestPoiRecords(
|
||||
+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistance, occupancy, load,
|
||||
+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load,
|
||||
+ 1, ret
|
||||
+ );
|
||||
+ return ret.isEmpty() ? null : ret.get(0);
|
||||
@ -478,14 +478,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ final Predicate<BlockPos> positionPredicate,
|
||||
+ final BlockPos sourcePosition,
|
||||
+ final int range, // distance on x y z axis
|
||||
+ final double maxDistance,
|
||||
+ final double maxDistanceSquared,
|
||||
+ final PoiManager.Occupancy occupancy,
|
||||
+ final boolean load,
|
||||
+ final int max,
|
||||
+ final List<PoiRecord> ret) {
|
||||
+ final Predicate<? super PoiRecord> occupancyFilter = occupancy.getTest();
|
||||
+
|
||||
+ final double maxDistanceSquared = maxDistance * maxDistance;
|
||||
+ final Double2ObjectRBTreeMap<List<PoiRecord>> closestRecords = new Double2ObjectRBTreeMap<>();
|
||||
+ int totalRecords = 0;
|
||||
+ double furthestDistanceSquared = maxDistanceSquared;
|
||||
|
Loading…
Reference in New Issue
Block a user