@@ -980,12 +980,19 @@ private void exportVisibleStructures() {
980980 for (ExportEntry exportEntry : exportEntries ) {
981981 BlockPos pos = exportEntry .pos ();
982982 JsonObject jsonEntry = new JsonObject ();
983- jsonEntry .addProperty ("feature" , exportEntry .feature ().getName ());
983+ MapFeature feature = exportEntry .feature ();
984+ String featureName = feature != null ? feature .getName () : exportEntry .label ();
985+ jsonEntry .addProperty ("feature" , featureName );
986+ jsonEntry .addProperty ("label" , exportEntry .label ());
984987 jsonEntry .addProperty ("number" , exportEntry .number ());
985988 jsonEntry .addProperty ("x" , pos .getX ());
986989 jsonEntry .addProperty ("y" , pos .getY ());
987990 jsonEntry .addProperty ("z" , pos .getZ ());
988991 jsonEntry .addProperty ("biome" , exportEntry .biome ());
992+ jsonEntry .addProperty ("structureId" , exportEntry .structureId ());
993+ if (exportEntry .datapackEntry () != null ) {
994+ jsonEntry .addProperty ("datapackId" , exportEntry .datapackEntry ().id ());
995+ }
989996 if (dimensionKey != null ) {
990997 jsonEntry .addProperty ("dimension" , dimensionKey .identifier ().toString ());
991998 }
@@ -1516,7 +1523,7 @@ private void exportVisibleStructuresToXaero() {
15161523 continue ;
15171524 }
15181525 occupiedCoords .add (coordKey );
1519- String name = "%s %d" .formatted (exportEntry .feature (). getName (), exportEntry .number ());
1526+ String name = "%s %d" .formatted (exportEntry .label (), exportEntry .number ());
15201527 String waypointLine = "waypoint:%s:%s:%d:%d:%d:%d:%s:%d:%s:%s:%d:%d:%s" .formatted (
15211528 encodeXaeroName (name ),
15221529 buildXaeroInitials (name ),
@@ -1556,25 +1563,44 @@ private void exportVisibleStructuresToXaero() {
15561563 }
15571564
15581565 private List <ExportEntry > collectVisibleExportEntries () {
1559- List <FeatureWidget > visibleWidgets = this .featureWidgets .stream ()
1560- .filter (widget -> Configs .ToggledFeatures .contains (widget .feature ))
1561- .filter (FeatureWidget ::withinBounds )
1562- .sorted (Comparator
1563- .comparing ((FeatureWidget widget ) -> widget .feature .getName ())
1564- .thenComparing (widget -> widget .featureLocation .getX ())
1565- .thenComparing (widget -> widget .featureLocation .getZ ()))
1566- .toList ();
1567- if (visibleWidgets .isEmpty ()) {
1566+ List <ExportCandidate > candidates = new ArrayList <>(this .featureWidgets .size () + this .customStructureWidgets .size ());
1567+ for (FeatureWidget widget : this .featureWidgets ) {
1568+ if (!Configs .ToggledFeatures .contains (widget .feature ())) {
1569+ continue ;
1570+ }
1571+ if (!widget .withinBounds ()) {
1572+ continue ;
1573+ }
1574+ MapFeature feature = widget .feature ();
1575+ candidates .add (new ExportCandidate (feature .getName (), feature .getName (), widget .featureLocation , feature , null , feature .getStructureId ()));
1576+ }
1577+ for (CustomStructureWidget widget : this .customStructureWidgets ) {
1578+ if (!widget .withinBounds ()) {
1579+ continue ;
1580+ }
1581+ DatapackStructureManager .StructureSetEntry entry = widget .entry ();
1582+ String tooltip = entry .tooltip ().getString ();
1583+ String label = tooltip .isBlank () ? entry .id () : tooltip ;
1584+ String key = "datapack:" + entry .id ();
1585+ candidates .add (new ExportCandidate (key , label , widget .featureLocation (), null , entry , -1 ));
1586+ }
1587+ if (candidates .isEmpty ()) {
15681588 return List .of ();
15691589 }
1570- Object2IntMap <MapFeature > featureCounts = new Object2IntOpenHashMap <>();
1590+ candidates .sort (Comparator
1591+ .comparing (ExportCandidate ::key )
1592+ .thenComparing (candidate -> candidate .pos ().getX ())
1593+ .thenComparing (candidate -> candidate .pos ().getZ ())
1594+ );
1595+ Object2IntMap <String > featureCounts = new Object2IntOpenHashMap <>();
15711596 featureCounts .defaultReturnValue (0 );
1572- List <ExportEntry > exportEntries = new ArrayList <>(visibleWidgets .size ());
1573- for (FeatureWidget widget : visibleWidgets ) {
1574- int nextIndex = featureCounts .getInt (widget .feature ) + 1 ;
1575- featureCounts .put (widget .feature , nextIndex );
1576- BlockPos pos = widget .featureLocation ;
1577- exportEntries .add (new ExportEntry (widget .feature , nextIndex , pos , this .getBiomeName (pos )));
1597+ List <ExportEntry > exportEntries = new ArrayList <>(candidates .size ());
1598+ for (ExportCandidate candidate : candidates ) {
1599+ String key = candidate .key ();
1600+ int nextIndex = featureCounts .getInt (key ) + 1 ;
1601+ featureCounts .put (key , nextIndex );
1602+ BlockPos pos = candidate .pos ();
1603+ exportEntries .add (new ExportEntry (candidate .feature (), candidate .datapackEntry (), key , candidate .label (), nextIndex , pos , this .getBiomeName (pos ), candidate .structureId ()));
15781604 }
15791605 return exportEntries ;
15801606 }
@@ -1639,7 +1665,29 @@ private static String buildXaeroInitials(String name) {
16391665 return initials .length () == 0 ? "WP" : initials .toString ();
16401666 }
16411667
1642- private record ExportEntry (MapFeature feature , int number , BlockPos pos , String biome ) {}
1668+ private record ExportEntry (
1669+ @ Nullable MapFeature feature ,
1670+ @ Nullable DatapackStructureManager .StructureSetEntry datapackEntry ,
1671+ String key ,
1672+ String label ,
1673+ int number ,
1674+ BlockPos pos ,
1675+ String biome ,
1676+ int structureId
1677+ ) {
1678+ public boolean isDatapack () {
1679+ return this .datapackEntry != null ;
1680+ }
1681+ }
1682+
1683+ private record ExportCandidate (
1684+ String key ,
1685+ String label ,
1686+ BlockPos pos ,
1687+ @ Nullable MapFeature feature ,
1688+ @ Nullable DatapackStructureManager .StructureSetEntry datapackEntry ,
1689+ int structureId
1690+ ) {}
16431691
16441692 private Path resolveXaeroWorldFolder (String worldIdentifier ) {
16451693 Path minimapDir = this .minecraft .gameDirectory .toPath ().resolve ("xaero" ).resolve ("minimap" );
@@ -3838,8 +3886,8 @@ private void openLootTableScreen() {
38383886 return ;
38393887 }
38403888 List <LootExportHelper .Target > targets = exportEntries .stream ()
3841- .filter (entry -> LocateCommand .LOOT_SUPPORTED_STRUCTURES .contains (entry .feature (). getStructureId ()))
3842- .map (entry -> new LootExportHelper .Target (entry .feature (). getStructureId (), entry .pos ()))
3889+ .filter (entry -> LocateCommand .LOOT_SUPPORTED_STRUCTURES .contains (entry .structureId ()))
3890+ .map (entry -> new LootExportHelper .Target (entry .structureId (), entry .pos ()))
38433891 .toList ();
38443892 if (targets .isEmpty ()) {
38453893 player .displayClientMessage (Component .literal ("No lootable structures in view." ), false );
0 commit comments