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:
Lulu13022002 2022-11-21 16:02:21 +01:00
parent b36d2af7d5
commit 944be7b031

View File

@ -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;