@@ -201,6 +201,19 @@ public ChestSearchScreen(Screen prev, Object ignored)
201201 this .openedByKeybind = (ignored instanceof Boolean && (Boolean )ignored );
202202 }
203203
204+ /**
205+ * Construct using a custom ChestManager (for example, lootsearch data).
206+ */
207+ public ChestSearchScreen (Screen prev ,
208+ net .wurstclient .chestsearch .ChestManager manager ,
209+ boolean openedByKeybind )
210+ {
211+ super (Component .literal ("Chest Search" ));
212+ this .prev = prev ;
213+ this .chestManager = manager == null ? new ChestManager () : manager ;
214+ this .openedByKeybind = openedByKeybind ;
215+ }
216+
204217 @ Override
205218 protected void init ()
206219 {
@@ -279,7 +292,8 @@ private void onSearchChanged(String q)
279292 currentQuery = qq ;
280293 lastMatchQuery = qq .toLowerCase (Locale .ROOT );
281294 matchCache .clear ();
282- this .chestManager = new ChestManager ();
295+ if (this .chestManager == null )
296+ this .chestManager = new ChestManager ();
283297 java .util .List <ChestEntry > raw =
284298 qq .isEmpty () ? new java .util .ArrayList <>(chestManager .all ())
285299 : new java .util .ArrayList <>(chestManager .search (qq ));
@@ -413,7 +427,19 @@ private java.util.List<ChestEntry> applyRadiusFilter(
413427 net .minecraft .client .Minecraft mc = WurstClient .MC ;
414428 if (mc == null || mc .player == null )
415429 return entries ;
416-
430+
431+ // If displaying LootChestManager data (seedmapper exports), skip
432+ // the ChestSearch display radius filter so all loot entries are shown.
433+ try
434+ {
435+ if (this .chestManager != null
436+ && this .chestManager .getClass ().getName ()
437+ .equals ("net.wurstclient.lootsearch.LootChestManager" ))
438+ {
439+ return entries ;
440+ }
441+ }catch (Throwable ignored )
442+ {}
417443 net .wurstclient .hacks .ChestSearchHack hack ;
418444 try
419445 {
@@ -504,6 +530,14 @@ private void rebuildRowButtons()
504530 searchField .getValue () == null ? "" : searchField .getValue ();
505531 java .util .List <ChestEntry .ItemEntry > matches =
506532 collectMatches (e , query );
533+ boolean isLootManager = false ;
534+ try
535+ {
536+ isLootManager = this .chestManager != null
537+ && this .chestManager .getClass ().getName ()
538+ .equals ("net.wurstclient.lootsearch.LootChestManager" );
539+ }catch (Throwable ignored )
540+ {}
507541 int matchLines = matches .isEmpty () ? 1 : matches .size ();
508542 int boxHeight = computeBoxHeight (pinnedEntry , matchLines );
509543 if (y + boxHeight < visibleTop )
@@ -520,76 +554,106 @@ private void rebuildRowButtons()
520554 .withStyle (style -> style
521555 .withColor (net .minecraft .ChatFormatting .GOLD ))
522556 : Component .literal ("ESP" );
523- Button espBtn = Button .builder (espLabel , b -> {
524- try
525- {
526- String dimLocal = normalizeDimension (e .dimension );
527- // Use this entry's clicked position (the block the
528- // player actually clicked when recording) so ESP draws
529- // on the expected chest half.
530- BlockPos useMin = e .getClickedPos ();
531- boolean exists = false ;
532- if (WurstClient .MC != null && WurstClient .MC .level != null )
533- {
534- var world = WurstClient .MC .level ;
535- var state = world .getBlockState (useMin );
536- boolean container = state != null && (state
537- .getBlock () instanceof net .minecraft .world .level .block .ChestBlock
538- || state
539- .getBlock () instanceof net .minecraft .world .level .block .BarrelBlock
540- || state
541- .getBlock () instanceof net .minecraft .world .level .block .ShulkerBoxBlock
542- || state
543- .getBlock () instanceof net .minecraft .world .level .block .DecoratedPotBlock
544- || state
545- .getBlock () instanceof net .minecraft .world .level .block .EnderChestBlock );
546- boolean hasBe = world .getBlockEntity (useMin ) != null ;
547- exists = container && hasBe ;
548- }
549- if (!exists )
557+ Button espBtn = null ;
558+ if (!isLootManager )
559+ {
560+ espBtn = Button .builder (espLabel , b -> {
561+ try
550562 {
551- try
563+ String dimLocal = normalizeDimension (e .dimension );
564+ // Use this entry's clicked position (the block the
565+ // player actually clicked when recording) so ESP draws
566+ // on the expected chest half.
567+ BlockPos useMin = e .getClickedPos ();
568+ boolean exists = false ;
569+ if (WurstClient .MC != null
570+ && WurstClient .MC .level != null )
552571 {
553- new ChestManager ().removeChest (e .serverIp ,
554- e .dimension , useMin .getX (), useMin .getY (),
555- useMin .getZ ());
556- }catch (Throwable ignored )
557- {}
558- this .chestManager = new ChestManager ();
559- onSearchChanged (searchField .getValue ());
572+ boolean isLootManagerInner = false ;
573+ try
574+ {
575+ isLootManagerInner = this .chestManager != null
576+ && this .chestManager .getClass ().getName ()
577+ .equals (
578+ "net.wurstclient.lootsearch.LootChestManager" );
579+ }catch (Throwable ignored )
580+ {}
581+ if (!isLootManagerInner )
582+ {
583+ var world = WurstClient .MC .level ;
584+ var state = world .getBlockState (useMin );
585+ boolean container = state != null && (state
586+ .getBlock () instanceof net .minecraft .world .level .block .ChestBlock
587+ || state
588+ .getBlock () instanceof net .minecraft .world .level .block .BarrelBlock
589+ || state
590+ .getBlock () instanceof net .minecraft .world .level .block .ShulkerBoxBlock
591+ || state
592+ .getBlock () instanceof net .minecraft .world .level .block .DecoratedPotBlock
593+ || state
594+ .getBlock () instanceof net .minecraft .world .level .block .EnderChestBlock );
595+ boolean hasBe =
596+ world .getBlockEntity (useMin ) != null ;
597+ exists = container && hasBe ;
598+ }else
599+ {
600+ // For loot export entries, they may not exist
601+ // as placed blocks in
602+ // the world; allow ESP drawing without removing
603+ // the entry.
604+ exists = true ;
605+ }
606+ }
607+ if (!exists )
608+ {
609+ try
610+ {
611+ new ChestManager ().removeChest (e .serverIp ,
612+ e .dimension , useMin .getX (), useMin .getY (),
613+ useMin .getZ ());
614+ }catch (Throwable ignored )
615+ {}
616+ this .chestManager = new ChestManager ();
617+ onSearchChanged (searchField .getValue ());
618+ minecraft .execute (this ::refreshPins );
619+ return ;
620+ }
621+ net .wurstclient .hacks .ChestSearchHack hack =
622+ WurstClient .INSTANCE .getHax ().chestSearchHack ;
623+ net .wurstclient .chestsearch .TargetHighlighter .INSTANCE
624+ .setColors (hack .getEspFillARGB (),
625+ hack .getEspLineARGB ());
626+ // render a single-block ESP at the canonical primary
627+ // position
628+ net .wurstclient .chestsearch .TargetHighlighter .INSTANCE
629+ .toggle (dimLocal , useMin , useMin ,
630+ hack .getEspTimeMs ());
560631 minecraft .execute (this ::refreshPins );
561- return ;
562- }
563- net .wurstclient .hacks .ChestSearchHack hack =
564- WurstClient .INSTANCE .getHax ().chestSearchHack ;
565- net .wurstclient .chestsearch .TargetHighlighter .INSTANCE
566- .setColors (hack .getEspFillARGB (),
567- hack .getEspLineARGB ());
568- // render a single-block ESP at the canonical primary
569- // position
570- net .wurstclient .chestsearch .TargetHighlighter .INSTANCE
571- .toggle (dimLocal , useMin , useMin , hack .getEspTimeMs ());
572- minecraft .execute (this ::refreshPins );
573- }catch (Throwable ignored )
574- {}
575- }).bounds (0 , btnY , 40 , 16 ).build ();
576- if (espActive )
577- espBtn .setTooltip (net .minecraft .client .gui .components .Tooltip
578- .create (Component .literal ("ESP active" )));
632+ }catch (Throwable ignored )
633+ {}
634+ }).bounds (0 , btnY , 40 , 16 ).build ();
635+ if (espActive )
636+ espBtn
637+ .setTooltip (net .minecraft .client .gui .components .Tooltip
638+ .create (Component .literal ("ESP active" )));
639+ }
579640 // position esp and wp buttons to the right side of the result box
580641 int boxRight = x + 340 ;
581642 int wpWidth = 56 ;
582- int espWidth = 40 ;
643+ int espWidth = isLootManager ? 0 : 40 ;
583644 int deleteWidth = 56 ;
584645 // Stack buttons vertically at the right edge (ESP, Waypoint,
585646 // Delete)
586647 int stackWidth = Math .max (Math .max (wpWidth , espWidth ), deleteWidth );
587648 int stackRight = boxRight - 6 ; // 6px padding from box edge
588649 int stackX = stackRight - stackWidth ;
589650 // place esp at top, wp below, delete below that
590- espBtn .setPosition (stackX + (stackWidth - espWidth ) / 2 , btnY );
591- addRenderableWidget (espBtn );
592- rowButtons .add (espBtn );
651+ if (!isLootManager && espBtn != null )
652+ {
653+ espBtn .setPosition (stackX + (stackWidth - espWidth ) / 2 , btnY );
654+ addRenderableWidget (espBtn );
655+ rowButtons .add (espBtn );
656+ }
593657 boolean hasWp = waypointActive ;
594658 Component wpLabel =
595659 hasWp
@@ -681,10 +745,12 @@ else if(p.contains("end"))
681745 // hide per-row buttons when their row is outside the visible
682746 // scrolling region so they don't overlap header/search UI
683747 boolean rowVisible = btnY >= visibleTop && btnY <= visibleBottom ;
684- espBtn .visible = rowVisible ;
748+ if (!isLootManager && espBtn != null )
749+ espBtn .visible = rowVisible ;
685750 wpBtn .visible = rowVisible ;
686751 delBtn .visible = rowVisible ;
687- espBtn .active = rowVisible ;
752+ if (!isLootManager && espBtn != null )
753+ espBtn .active = rowVisible ;
688754 wpBtn .active = rowVisible ;
689755 delBtn .active = rowVisible ;
690756 delBtn .setTooltip (net .minecraft .client .gui .components .Tooltip
0 commit comments