|
10 | 10 | import com.mojang.blaze3d.vertex.PoseStack; |
11 | 11 | import java.util.ArrayDeque; |
12 | 12 | import java.util.ArrayList; |
13 | | -import java.util.Comparator; |
14 | 13 | import java.util.HashMap; |
15 | 14 | import java.util.HashSet; |
16 | 15 | import java.util.List; |
17 | | -import java.util.PriorityQueue; |
18 | 16 | import java.util.stream.Collectors; |
19 | 17 | import net.minecraft.core.BlockPos; |
20 | 18 | import net.minecraft.core.registries.BuiltInRegistries; |
|
28 | 26 | import net.minecraft.world.entity.Entity; |
29 | 27 | import net.minecraft.world.entity.animal.golem.IronGolem; |
30 | 28 | import net.minecraft.world.entity.npc.villager.Villager; |
| 29 | +import net.minecraft.world.entity.vehicle.boat.AbstractChestBoat; |
| 30 | +import net.minecraft.world.entity.vehicle.minecart.MinecartChest; |
| 31 | +import net.minecraft.world.entity.vehicle.minecart.MinecartHopper; |
31 | 32 | import net.minecraft.world.level.block.BarrelBlock; |
32 | 33 | import net.minecraft.world.level.block.Block; |
33 | 34 | import net.minecraft.world.level.block.Blocks; |
34 | 35 | import net.minecraft.world.level.block.ChestBlock; |
| 36 | +import net.minecraft.world.level.block.DecoratedPotBlock; |
35 | 37 | import net.minecraft.world.level.block.DoorBlock; |
36 | 38 | import net.minecraft.world.level.block.HopperBlock; |
37 | 39 | import net.minecraft.world.level.block.DispenserBlock; |
|
41 | 43 | import net.minecraft.world.level.block.entity.BlockEntity; |
42 | 44 | import net.minecraft.world.level.block.entity.ChestBlockEntity; |
43 | 45 | import net.minecraft.world.level.block.entity.BarrelBlockEntity; |
| 46 | +import net.minecraft.world.level.block.entity.CrafterBlockEntity; |
| 47 | +import net.minecraft.world.level.block.entity.DecoratedPotBlockEntity; |
| 48 | +import net.minecraft.world.level.block.entity.DropperBlockEntity; |
| 49 | +import net.minecraft.world.level.block.entity.EnderChestBlockEntity; |
44 | 50 | import net.minecraft.world.level.block.entity.HopperBlockEntity; |
45 | 51 | import net.minecraft.world.level.block.entity.DispenserBlockEntity; |
46 | 52 | import net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity; |
|
70 | 76 | import net.wurstclient.settings.SliderSetting; |
71 | 77 | import net.wurstclient.util.BlockUtils; |
72 | 78 | import net.wurstclient.util.ChatUtils; |
| 79 | +import net.wurstclient.util.EspLimitUtils; |
| 80 | +import net.wurstclient.util.LootrModCompat; |
73 | 81 | import net.wurstclient.util.RenderUtils; |
74 | 82 | import net.wurstclient.util.RotationUtils; |
75 | 83 | import net.wurstclient.util.chunk.ChunkUtils; |
@@ -407,44 +415,109 @@ private void refreshOpenedChestCacheIfNeeded() |
407 | 415 | private List<BlockEntity> getNearestLoadedBlockEntities(int limit) |
408 | 416 | { |
409 | 417 | var eyesPos = RotationUtils.getEyesPos(); |
410 | | - PriorityQueue<BlockEntity> heap = new PriorityQueue<>(limit + 1, |
411 | | - Comparator.comparingDouble( |
412 | | - (BlockEntity be) -> be.getBlockPos().distToCenterSqr(eyesPos)) |
413 | | - .reversed()); |
414 | | - |
415 | | - ChunkUtils.getLoadedBlockEntities().forEach(be -> { |
416 | | - if(heap.size() < limit) |
417 | | - heap.offer(be); |
418 | | - else if(be.getBlockPos().distToCenterSqr(eyesPos) < heap.peek() |
419 | | - .getBlockPos().distToCenterSqr(eyesPos)) |
420 | | - { |
421 | | - heap.poll(); |
422 | | - heap.offer(be); |
423 | | - } |
424 | | - }); |
425 | | - |
426 | | - return new ArrayList<>(heap); |
| 418 | + return EspLimitUtils.collectNearest(ChunkUtils.getLoadedBlockEntities(), |
| 419 | + limit, be -> be.getBlockPos().distToCenterSqr(eyesPos), |
| 420 | + this::isRelevantBlockEntityTarget); |
427 | 421 | } |
428 | 422 |
|
429 | 423 | private List<Entity> getNearestEntitiesForRendering(int limit) |
430 | 424 | { |
431 | | - PriorityQueue<Entity> heap = new PriorityQueue<>(limit + 1, |
432 | | - Comparator.comparingDouble((Entity e) -> e.distanceToSqr(MC.player)) |
433 | | - .reversed()); |
| 425 | + return EspLimitUtils.collectNearest(MC.level.entitiesForRendering(), |
| 426 | + limit, e -> e.distanceToSqr(MC.player), |
| 427 | + this::isRelevantEntityTarget); |
| 428 | + } |
| 429 | + |
| 430 | + private boolean isRelevantBlockEntityTarget(BlockEntity be) |
| 431 | + { |
| 432 | + if(be == null) |
| 433 | + return false; |
434 | 434 |
|
435 | | - for(Entity entity : MC.level.entitiesForRendering()) |
436 | | - { |
437 | | - if(heap.size() < limit) |
438 | | - heap.offer(entity); |
439 | | - else if(entity.distanceToSqr(MC.player) < heap.peek() |
440 | | - .distanceToSqr(MC.player)) |
441 | | - { |
442 | | - heap.poll(); |
443 | | - heap.offer(entity); |
444 | | - } |
445 | | - } |
| 435 | + if(groups.pots.isEnabled() && be instanceof DecoratedPotBlockEntity) |
| 436 | + return true; |
| 437 | + |
| 438 | + if(groups.furnaces.isEnabled() |
| 439 | + && be instanceof net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity) |
| 440 | + return true; |
| 441 | + |
| 442 | + if(groups.crafters.isEnabled() && be instanceof CrafterBlockEntity) |
| 443 | + return true; |
| 444 | + |
| 445 | + if(groups.barrels.isEnabled() && LootrModCompat.isLootrBarrel(be)) |
| 446 | + return true; |
| 447 | + if(groups.shulkerBoxes.isEnabled() |
| 448 | + && LootrModCompat.isLootrShulkerBox(be)) |
| 449 | + return true; |
| 450 | + if(groups.trapChests.isEnabled() |
| 451 | + && LootrModCompat.isLootrTrappedChest(be)) |
| 452 | + return true; |
| 453 | + |
| 454 | + BlockState state = be.getBlockState(); |
| 455 | + if(state == null) |
| 456 | + return false; |
| 457 | + |
| 458 | + Block block = state.getBlock(); |
| 459 | + if(block instanceof ChestBlock) |
| 460 | + return groups.normalChests.isEnabled() |
| 461 | + || groups.trapChests.isEnabled(); |
446 | 462 |
|
447 | | - return new ArrayList<>(heap); |
| 463 | + if(block == Blocks.ENDER_CHEST) |
| 464 | + return groups.enderChests.isEnabled(); |
| 465 | + |
| 466 | + if(block instanceof BarrelBlock) |
| 467 | + return groups.barrels.isEnabled(); |
| 468 | + |
| 469 | + if(block instanceof ShulkerBoxBlock) |
| 470 | + return groups.shulkerBoxes.isEnabled(); |
| 471 | + |
| 472 | + if(block instanceof HopperBlock) |
| 473 | + return groups.hoppers.isEnabled(); |
| 474 | + |
| 475 | + if(block == Blocks.DROPPER) |
| 476 | + return groups.droppers.isEnabled(); |
| 477 | + |
| 478 | + if(block instanceof DispenserBlock) |
| 479 | + return groups.dispensers.isEnabled(); |
| 480 | + |
| 481 | + if(block == Blocks.CRAFTER) |
| 482 | + return groups.crafters.isEnabled(); |
| 483 | + |
| 484 | + if(block == Blocks.FURNACE || block == Blocks.BLAST_FURNACE |
| 485 | + || block == Blocks.SMOKER) |
| 486 | + return groups.furnaces.isEnabled(); |
| 487 | + |
| 488 | + if(block instanceof DecoratedPotBlock) |
| 489 | + return groups.pots.isEnabled(); |
| 490 | + |
| 491 | + // Fallbacks for odd states/modded cases. |
| 492 | + if(be instanceof EnderChestBlockEntity) |
| 493 | + return groups.enderChests.isEnabled(); |
| 494 | + if(be instanceof BarrelBlockEntity) |
| 495 | + return groups.barrels.isEnabled(); |
| 496 | + if(be instanceof HopperBlockEntity) |
| 497 | + return groups.hoppers.isEnabled(); |
| 498 | + if(be instanceof DropperBlockEntity) |
| 499 | + return groups.droppers.isEnabled(); |
| 500 | + if(be instanceof DispenserBlockEntity) |
| 501 | + return groups.dispensers.isEnabled(); |
| 502 | + |
| 503 | + return false; |
| 504 | + } |
| 505 | + |
| 506 | + private boolean isRelevantEntityTarget(Entity entity) |
| 507 | + { |
| 508 | + if(entity == null) |
| 509 | + return false; |
| 510 | + |
| 511 | + if(groups.chestCarts.isEnabled() && entity instanceof MinecartChest) |
| 512 | + return true; |
| 513 | + |
| 514 | + if(groups.chestBoats.isEnabled() && entity instanceof AbstractChestBoat) |
| 515 | + return true; |
| 516 | + |
| 517 | + if(groups.hopperCarts.isEnabled() && entity instanceof MinecartHopper) |
| 518 | + return true; |
| 519 | + |
| 520 | + return false; |
448 | 521 | } |
449 | 522 |
|
450 | 523 | @Override |
|
0 commit comments