4444import net .minecraft .world .level .block .entity .HopperBlockEntity ;
4545import net .minecraft .world .level .block .entity .DispenserBlockEntity ;
4646import net .minecraft .world .level .block .entity .TrialSpawnerBlockEntity ;
47- import net .minecraft .world .level .block .entity .SpawnerBlockEntity ;
48- import net .minecraft .world .level .chunk .LevelChunk ;
49- import net .minecraft .world .level .chunk .LevelChunkSection ;
50- import net .minecraft .world .level .ChunkPos ;
51- import net .minecraft .world .phys .AABB ;
52- import net .minecraft .world .phys .Vec3 ;
47+ import net .minecraft .world .level .block .entity .SpawnerBlockEntity ;
48+ import net .minecraft .world .level .chunk .LevelChunk ;
49+ import net .minecraft .world .level .chunk .LevelChunkSection ;
50+ import net .minecraft .world .level .ChunkPos ;
51+ import net .minecraft .world .level .Level ;
52+ import net .minecraft .world .phys .AABB ;
53+ import net .minecraft .world .phys .Vec3 ;
5354import net .wurstclient .Category ;
5455import net .wurstclient .events .CameraTransformViewBobbingListener ;
5556import net .wurstclient .events .PacketInputListener ;
@@ -145,10 +146,10 @@ public class ChestEspHack extends Hack implements UpdateListener,
145146 "Only show buried containers (non-air above for chests/barrels; blocked opening side for shulkers)." ,
146147 false );
147148
148- private final CheckboxSetting filterNearSpawners = new CheckboxSetting (
149- "Filter spawners" ,
150- "Hides single chests that are near a mob spawner. Does not affect double chests or shulkers." ,
151- false );
149+ private final CheckboxSetting filterNearSpawners = new CheckboxSetting (
150+ "Filter spawners" ,
151+ "Hides single chests that are near a mob spawner in the Overworld . Does not affect double chests or shulkers." ,
152+ false );
152153
153154 private final CheckboxSetting filterTrialChambers = new CheckboxSetting (
154155 "Filter trial chambers" ,
@@ -301,8 +302,8 @@ public void onUpdate()
301302 // Build environmental caches first so we can pre-filter before adding
302303 invalidateEnvFilterCacheIfNeeded ();
303304 refreshEnvironmentalCaches ();
304- preFilteredEnv = MC .level != null && (filterNearSpawners . isChecked ()
305- || filterTrialChambers .isChecked () || filterVillages .isChecked ());
305+ preFilteredEnv = MC .level != null && (isSpawnerFilterActive ()
306+ || filterTrialChambers .isChecked () || filterVillages .isChecked ());
306307
307308 double yLimit = aboveGroundY .getValue ();
308309 boolean enforceAboveGround = onlyAboveGround .isChecked ();
@@ -546,10 +547,10 @@ private void renderBoxes(PoseStack matrixStack)
546547 String curDim = MC .level == null ? "overworld"
547548 : MC .level .dimension ().identifier ().getPath ();
548549
549- boolean applyEnvFilters = MC .level != null && !preFilteredEnv
550- && (filterNearSpawners . isChecked ()
551- || filterTrialChambers .isChecked ()
552- || filterVillages .isChecked ());
550+ boolean applyEnvFilters = MC .level != null && !preFilteredEnv
551+ && (isSpawnerFilterActive ()
552+ || filterTrialChambers .isChecked ()
553+ || filterVillages .isChecked ());
553554
554555 for (ChestEspGroup group : groups .allGroups )
555556 {
@@ -904,10 +905,10 @@ private void renderTracers(PoseStack matrixStack, float partialTicks)
904905 : MC .level .dimension ().identifier ().getPath ();
905906 }
906907
907- boolean applyEnvFilters = MC .level != null && !preFilteredEnv
908- && (filterNearSpawners . isChecked ()
909- || filterTrialChambers .isChecked ()
910- || filterVillages .isChecked ());
908+ boolean applyEnvFilters = MC .level != null && !preFilteredEnv
909+ && (isSpawnerFilterActive ()
910+ || filterTrialChambers .isChecked ()
911+ || filterVillages .isChecked ());
911912
912913 for (ChestEspGroup group : groups .allGroups )
913914 {
@@ -1376,10 +1377,10 @@ private void refreshEnvironmentalCaches()
13761377 lastEnvironmentRefreshAnchor = currentAnchor .immutable ();
13771378 lastEnvironmentRefreshDimension = currentDimension ;
13781379
1379- if (filterNearSpawners . isChecked ())
1380- cachedSpawners = collectSpawnerPositions ();
1381- else
1382- cachedSpawners = List .of ();
1380+ if (isSpawnerFilterActive ())
1381+ cachedSpawners = collectSpawnerPositions ();
1382+ else
1383+ cachedSpawners = List .of ();
13831384
13841385 if (filterTrialChambers .isChecked ())
13851386 cachedTrialSpawners = collectTrialSpawnerPositions ();
@@ -1500,9 +1501,9 @@ && isInTrialChamberArea(barrelPos))
15001501 continue ;
15011502 }
15021503
1503- if (filterNearSpawners . isChecked ()
1504- && isNearSpawner (singleChestPos , 7 ))
1505- continue ;
1504+ if (isSpawnerFilterActive ()
1505+ && isNearSpawner (singleChestPos , 7 ))
1506+ continue ;
15061507
15071508 if (filterTrialChambers .isChecked ()
15081509 && isInTrialChamberArea (singleChestPos ))
@@ -1543,24 +1544,26 @@ private boolean computeShouldFilterBlockEntityByEnvironment(BlockEntity be)
15431544 BlockPos pos = be .getBlockPos ();
15441545 BlockState state = be .getBlockState ();
15451546
1546- // Chest-specific single/double handling
1547- if (be instanceof ChestBlockEntity )
1548- {
1549- boolean isSingle = true ;
1550- if (state != null && state .hasProperty (ChestBlock .TYPE ))
1551- isSingle = state .getValue (ChestBlock .TYPE ) == ChestType .SINGLE ;
1552-
1553- if (isSingle )
1554- {
1555- if (filterNearSpawners .isChecked () && isNearSpawner (pos , 7 ))
1556- return true ;
1557- if (filterTrialChambers .isChecked () && isInTrialChamberArea (pos ))
1558- return true ;
1559- if (filterVillages .isChecked () && isLikelyVillageChest (pos ))
1560- return true ;
1561- }
1562- return false ;
1563- }
1547+ // Chest-specific single/double handling
1548+ if (be instanceof ChestBlockEntity )
1549+ {
1550+ // Be strict: environment filters apply only to confirmed single
1551+ // chests. If chest type can't be read, don't filter it.
1552+ if (state == null || !state .hasProperty (ChestBlock .TYPE ))
1553+ return false ;
1554+
1555+ if (state .getValue (ChestBlock .TYPE ) != ChestType .SINGLE )
1556+ return false ;
1557+
1558+ if (isSpawnerFilterActive () && isNearSpawner (pos , 7 ))
1559+ return true ;
1560+ if (filterTrialChambers .isChecked () && isInTrialChamberArea (pos ))
1561+ return true ;
1562+ if (filterVillages .isChecked () && isLikelyVillageChest (pos ))
1563+ return true ;
1564+
1565+ return false ;
1566+ }
15641567
15651568 // Barrels in Trial Chambers
15661569 if (be instanceof BarrelBlockEntity )
@@ -1619,22 +1622,22 @@ private BlockPos getSingleChestPosIfApplicable(AABB box)
16191622 if (b instanceof ShulkerBoxBlock )
16201623 return null ;
16211624
1622- if (b instanceof ChestBlock )
1623- {
1624- chestCount ++;
1625- if (foundChest == null )
1626- foundChest = pos ;
1627-
1628- if (state .hasProperty (ChestBlock .TYPE ))
1629- {
1630- ChestType t = state . getValue ( ChestBlock . TYPE );
1631- if ( t != ChestType . SINGLE )
1632- return null ;
1633- }
1634-
1635- if (chestCount > 1 )
1636- return null ;
1637- }
1625+ if (b instanceof ChestBlock )
1626+ {
1627+ chestCount ++;
1628+ if (foundChest == null )
1629+ foundChest = pos ;
1630+
1631+ if (! state .hasProperty (ChestBlock .TYPE ))
1632+ return null ;
1633+
1634+ ChestType t = state . getValue ( ChestBlock . TYPE );
1635+ if ( t != ChestType . SINGLE )
1636+ return null ;
1637+
1638+ if (chestCount > 1 )
1639+ return null ;
1640+ }
16381641 }
16391642 }
16401643 }
@@ -1696,10 +1699,13 @@ private boolean shouldSkipSingleChest(BlockEntity be)
16961699 return state .getValue (ChestBlock .TYPE ) == ChestType .SINGLE ;
16971700 }
16981701
1699- private boolean isNearSpawner (BlockPos center , int range )
1700- {
1701- if (isNearCachedSpawner (center , range ))
1702- return true ;
1702+ private boolean isNearSpawner (BlockPos center , int range )
1703+ {
1704+ if (!isSpawnerFilterActive ())
1705+ return false ;
1706+
1707+ if (isNearCachedSpawner (center , range ))
1708+ return true ;
17031709
17041710 // If we already have a stable non-empty spawner cache and no nearby
17051711 // hit,
@@ -1709,8 +1715,18 @@ private boolean isNearSpawner(BlockPos center, int range)
17091715
17101716 // Fallback to block-state scan so newly streamed areas don't briefly
17111717 // render near-spawner chests before block-entity caches catch up.
1712- return isNearSpawnerBlock (center , range );
1713- }
1718+ return isNearSpawnerBlock (center , range );
1719+ }
1720+
1721+ private boolean isSpawnerFilterActive ()
1722+ {
1723+ return filterNearSpawners .isChecked () && isInOverworld ();
1724+ }
1725+
1726+ private boolean isInOverworld ()
1727+ {
1728+ return MC .level != null && MC .level .dimension ().equals (Level .OVERWORLD );
1729+ }
17141730
17151731 private boolean isNearCachedSpawner (BlockPos center , int range )
17161732 {
0 commit comments