Skip to content

Commit f71411d

Browse files
committed
Add nether portal to POI search test
1 parent 2242659 commit f71411d

File tree

2 files changed

+57
-3
lines changed
  • common/src/main/java/net/caffeinemc/mods/lithium/common/world/interests
  • fabric/src/gametest/java/net/caffeinemc/mods/lithium/fabric/gametest/mixin/ai/poi

2 files changed

+57
-3
lines changed

common/src/main/java/net/caffeinemc/mods/lithium/common/world/interests/PoiOrdering.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import net.minecraft.world.entity.ai.village.poi.PoiSection;
88
import net.minecraft.world.level.ChunkPos;
99

10+
import java.util.Comparator;
1011
import java.util.List;
1112
import java.util.Optional;
1213

@@ -47,6 +48,10 @@ default void checkOrderOrThrow(BlockPos center, PoiManager poiManager, List<Bloc
4748
}
4849
}
4950

51+
default Comparator<BlockPos> getAsComparator(BlockPos center, PoiManager poiManager) {
52+
return (posA, posB) -> compare(center, poiManager, posA, posB);
53+
}
54+
5055
int compare(BlockPos center, PoiManager poiManager, BlockPos posA, BlockPos posB);
5156

5257

@@ -144,4 +149,27 @@ public int compare(BlockPos center, PoiManager poiManager, BlockPos posA, BlockP
144149
return InSquare.INSTANCE.compare(center, poiManager, posA, posB);
145150
}
146151
}
152+
153+
record L2ThenMinYThenInSquare() implements PoiOrdering {
154+
155+
public static final L2ThenMinYThenInSquare INSTANCE = new L2ThenMinYThenInSquare();
156+
157+
@Override
158+
public int compare(BlockPos center, PoiManager poiManager, BlockPos posA, BlockPos posB) {
159+
double distASq = center.distSqr(posA);
160+
double distBSq = center.distSqr(posB);
161+
162+
int orderDist = Double.compare(distBSq, distASq);
163+
if (orderDist != 0) {
164+
return orderDist;
165+
}
166+
167+
int orderY = Integer.compare(posA.getY(), posB.getY());
168+
if (orderY != 0) {
169+
return orderY;
170+
}
171+
172+
return InSquare.INSTANCE.compare(center, poiManager, posA, posB);
173+
}
174+
}
147175
}

fabric/src/gametest/java/net/caffeinemc/mods/lithium/fabric/gametest/mixin/ai/poi/POI_Search.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616
import net.minecraft.world.entity.ai.village.poi.PoiTypes;
1717
import net.minecraft.world.level.ChunkPos;
1818
import net.minecraft.world.level.block.Blocks;
19+
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
20+
import net.minecraft.world.level.border.WorldBorder;
1921

2022
import java.lang.reflect.Method;
23+
import java.util.Comparator;
2124
import java.util.List;
2225
import java.util.Optional;
2326
import java.util.function.Predicate;
@@ -27,8 +30,9 @@ public class POI_Search implements CustomTestMethodInvoker {
2730

2831
@GameTest(manualOnly = true)
2932
public void test(GameTestHelper context, BlockPos center, RandomSource randomSource) {
30-
PoiManager poiManager = context.getLevel().getPoiManager();
31-
Predicate<Holder<PoiType>> predicate = holder -> holder.is(PoiTypes.SHEPHERD);
33+
ServerLevel serverLevel = context.getLevel();
34+
PoiManager poiManager = serverLevel.getPoiManager();
35+
Predicate<Holder<PoiType>> predicate = holder -> holder.is(PoiTypes.NETHER_PORTAL);
3236

3337
long countInRange = poiManager.getCountInRange(predicate, center, 128, PoiManager.Occupancy.ANY);
3438

@@ -50,6 +54,28 @@ public void test(GameTestHelper context, BlockPos center, RandomSource randomSou
5054
List<BlockPos> allClosestFirstWithTypePositions = poiManager.findAllClosestFirstWithType(predicate, blockPos1 -> true, center, 128, PoiManager.Occupancy.ANY).map(Pair::getSecond).collect(Collectors.toList());
5155
PoiOrdering.L2ThenInSquare.INSTANCE.checkOrderOrThrow(center, poiManager, allClosestFirstWithTypePositions);
5256

57+
boolean fromOverworld = randomSource.nextBoolean();
58+
WorldBorder worldBorder = serverLevel.getWorldBorder();
59+
Optional<BlockPos> closestPortalPosition = serverLevel.getPortalForcer().findClosestPortalPosition(center, fromOverworld, worldBorder);
60+
int radius = fromOverworld ? 16 : 128;
61+
List<BlockPos> closestPortalPositions =
62+
poiManager.getInSquare(holder -> holder.is(PoiTypes.NETHER_PORTAL), center, radius, PoiManager.Occupancy.ANY)
63+
.map(PoiRecord::getPos)
64+
.filter(worldBorder::isWithinBounds)
65+
.filter(blockPosx -> serverLevel.getBlockState(blockPosx).hasProperty(BlockStateProperties.HORIZONTAL_AXIS))
66+
.sorted(Comparator.comparingDouble((BlockPos blockPos2) -> blockPos2.distSqr(center)).thenComparingInt(BlockPos::getY))
67+
.toList();
68+
PoiOrdering.L2ThenMinYThenInSquare.INSTANCE.checkOrderOrThrow(center, poiManager, closestPortalPositions);
69+
if (closestPortalPositions.isEmpty() != closestPortalPosition.isEmpty()) {
70+
throw new IllegalStateException("findClosestPortalPosition() emptiness does not match sorted and filtered getInSquare() emptiness");
71+
} else if (closestPortalPosition.isPresent()) {
72+
BlockPos closestPos = closestPortalPosition.get();
73+
if (!closestPortalPositions.getFirst().equals(closestPos)) {
74+
throw new IllegalStateException("findClosestPortalPosition() result is not the first of sorted and filtered getInSquare()");
75+
}
76+
}
77+
78+
5379
Optional<BlockPos> firstOfAll = poiManager.find(predicate, blockPos -> true, center, 128, PoiManager.Occupancy.ANY);
5480
if (firstOfAll.isEmpty() != inRangePositions.isEmpty()) {
5581
throw new IllegalStateException("find() result presence does not match getInRange() emptiness");
@@ -175,7 +201,7 @@ public void invokeTestMethod(GameTestHelper context, Method method) throws Refle
175201
for (BlockPos blockPos : BlockPos.betweenClosed(x - radius, y - radius, z - radius, x + radius, y + radius, z + radius)) {
176202
if (random.nextFloat() < randomPct && level.isInWorldBounds(blockPos)) {
177203
poiCount++;
178-
level.setBlock(blockPos, Blocks.LOOM.defaultBlockState(), 0);
204+
level.setBlock(blockPos, Blocks.NETHER_PORTAL.defaultBlockState(), 0);
179205
}
180206
}
181207

0 commit comments

Comments
 (0)