@@ -44,11 +44,68 @@ private LootExportHelper() {
4444 }
4545
4646 public static Result exportLoot (Minecraft minecraft , MemorySegment biomeGenerator , long seed , int version , int dimension , int biomeScale , String dimensionName , int centerX , int centerZ , int radius , List <Target > targets ) throws IOException {
47- if (targets .isEmpty ()) {
47+ List <LootEntry > entries = collectLootEntries (minecraft , biomeGenerator , seed , version , dimension , biomeScale , targets );
48+ if (entries .isEmpty ()) {
4849 return new Result (null , 0 );
4950 }
5051
5152 JsonArray structuresArray = new JsonArray ();
53+ for (LootEntry entry : entries ) {
54+ JsonObject entryObj = new JsonObject ();
55+ entryObj .addProperty ("id" , entry .id ());
56+ entryObj .addProperty ("type" , entry .type ());
57+ entryObj .addProperty ("x" , entry .pos ().getX ());
58+ entryObj .addProperty ("y" , entry .pos ().getY ());
59+ entryObj .addProperty ("z" , entry .pos ().getZ ());
60+ JsonArray items = new JsonArray ();
61+ for (LootItem item : entry .items ()) {
62+ JsonObject itemObj = new JsonObject ();
63+ itemObj .addProperty ("slot" , item .slot ());
64+ itemObj .addProperty ("count" , item .count ());
65+ itemObj .addProperty ("itemId" , item .itemId ());
66+ itemObj .addProperty ("id" , item .itemId ());
67+ itemObj .addProperty ("displayName" , item .displayName ());
68+ itemObj .addProperty ("nbt" , item .nbt ());
69+ JsonArray enchantments = new JsonArray ();
70+ JsonArray enchantmentLevels = new JsonArray ();
71+ for (String enchantment : item .enchantments ()) {
72+ enchantments .add (enchantment );
73+ }
74+ for (Integer level : item .enchantmentLevels ()) {
75+ enchantmentLevels .add (level );
76+ }
77+ itemObj .add ("enchantments" , enchantments );
78+ itemObj .add ("enchantmentLevels" , enchantmentLevels );
79+ items .add (itemObj );
80+ }
81+ entryObj .add ("items" , items );
82+ structuresArray .add (entryObj );
83+ }
84+
85+ JsonObject root = new JsonObject ();
86+ root .addProperty ("seed" , seed );
87+ root .addProperty ("dimension" , dimensionName == null ? Integer .toString (dimension ) : dimensionName );
88+ root .addProperty ("center_x" , centerX );
89+ root .addProperty ("center_z" , centerZ );
90+ root .addProperty ("radius" , radius );
91+ root .addProperty ("minecraftVersion" , SharedConstants .getCurrentVersion ().name ());
92+ root .add ("structures" , structuresArray );
93+
94+ Path lootDir = minecraft .gameDirectory .toPath ().resolve ("SeedMapper" ).resolve ("loot" );
95+ Files .createDirectories (lootDir );
96+ String serverId = resolveServerId (minecraft );
97+ String timestamp = EXPORT_TIMESTAMP .format (LocalDateTime .now ());
98+ Path exportFile = lootDir .resolve ("%s_%s-%s.json" .formatted (serverId , Long .toString (seed ), timestamp ));
99+ Files .writeString (exportFile , GSON .toJson (root ), StandardCharsets .UTF_8 , StandardOpenOption .CREATE , StandardOpenOption .TRUNCATE_EXISTING );
100+ return new Result (exportFile , structuresArray .size ());
101+ }
102+
103+ public static List <LootEntry > collectLootEntries (Minecraft minecraft , MemorySegment biomeGenerator , long seed , int version , int dimension , int biomeScale , List <Target > targets ) {
104+ if (targets .isEmpty ()) {
105+ return List .of ();
106+ }
107+
108+ List <LootEntry > entries = new java .util .ArrayList <>();
52109
53110 for (Target target : targets ) {
54111 try (Arena arena = Arena .ofConfined ()) {
@@ -94,29 +151,24 @@ public static Result exportLoot(Minecraft minecraft, MemorySegment biomeGenerato
94151 Cubiomes .set_loot_seed (lootTableContext , lootSeed );
95152 Cubiomes .generate_loot (lootTableContext );
96153 int lootCount = LootTableContext .generated_item_count (lootTableContext );
97- JsonArray items = new JsonArray ( );
154+ List < LootItem > items = new java . util . ArrayList <>( lootCount );
98155 for (int lootIdx = 0 ; lootIdx < lootCount ; lootIdx ++) {
99156 MemorySegment itemStack = ItemStack .asSlice (LootTableContext .generated_items (lootTableContext ), lootIdx );
100157 int itemId = Cubiomes .get_global_item_id (lootTableContext , ItemStack .item (itemStack ));
101158 String itemName = Cubiomes .global_id2item_name (itemId , version ).getString (0 );
102- JsonObject itemObj = new JsonObject ();
103- itemObj .addProperty ("slot" , lootIdx );
104- itemObj .addProperty ("count" , ItemStack .count (itemStack ));
105- itemObj .addProperty ("itemId" , itemName );
106- itemObj .addProperty ("id" , itemName );
159+ int count = ItemStack .count (itemStack );
107160
161+ String displayName = itemName ;
162+ String nbt = itemName ;
108163 Item mcItem = ItemAndEnchantmentsPredicateArgument .ITEM_ID_TO_MC .get (itemId );
109164 if (mcItem != null ) {
110- net .minecraft .world .item .ItemStack mcStack = new net .minecraft .world .item .ItemStack (mcItem , ItemStack .count (itemStack ));
111- itemObj .addProperty ("displayName" , mcStack .getHoverName ().getString ());
112- itemObj .addProperty ("nbt" , mcStack .toString ());
113- } else {
114- itemObj .addProperty ("displayName" , itemName );
115- itemObj .addProperty ("nbt" , itemName );
165+ net .minecraft .world .item .ItemStack mcStack = new net .minecraft .world .item .ItemStack (mcItem , count );
166+ displayName = mcStack .getHoverName ().getString ();
167+ nbt = mcStack .toString ();
116168 }
117169
118- JsonArray enchantments = new JsonArray ();
119- JsonArray enchantmentLevels = new JsonArray ();
170+ List < String > enchantments = new java . util . ArrayList <> ();
171+ List < Integer > enchantmentLevels = new java . util . ArrayList <> ();
120172 MemorySegment enchantmentsInternal = ItemStack .enchantments (itemStack );
121173 int enchantmentCount = ItemStack .enchantment_count (itemStack );
122174 for (int enchantmentIdx = 0 ; enchantmentIdx < enchantmentCount ; enchantmentIdx ++) {
@@ -129,21 +181,13 @@ public static Result exportLoot(Minecraft minecraft, MemorySegment biomeGenerato
129181 enchantments .add (enchantmentName );
130182 enchantmentLevels .add (EnchantInstance .level (enchantInstance ));
131183 }
132- itemObj .add ("enchantments" , enchantments );
133- itemObj .add ("enchantmentLevels" , enchantmentLevels );
134- items .add (itemObj );
184+ items .add (new LootItem (lootIdx , count , itemName , displayName , nbt , enchantments , enchantmentLevels ));
135185 }
136186
137187 MemorySegment chestPos = Pos .asSlice (chestPoses , chestIdx );
138- JsonObject entry = new JsonObject ();
139188 String structName = Cubiomes .struct2str (structure ).getString (0 );
140- entry .addProperty ("id" , structName + "-" + pieceName + "-" + chestIdx );
141- entry .addProperty ("type" , structName );
142- entry .addProperty ("x" , Pos .x (chestPos ));
143- entry .addProperty ("y" , 0 );
144- entry .addProperty ("z" , Pos .z (chestPos ));
145- entry .add ("items" , items );
146- structuresArray .add (entry );
189+ BlockPos entryPos = new BlockPos (Pos .x (chestPos ), 0 , Pos .z (chestPos ));
190+ entries .add (new LootEntry (structName + "-" + pieceName + "-" + chestIdx , structName , pieceName , entryPos , items ));
147191 } finally {
148192 CubiomesCompat .freeLootTablePools (lootTableContext );
149193 }
@@ -152,26 +196,7 @@ public static Result exportLoot(Minecraft minecraft, MemorySegment biomeGenerato
152196 }
153197 }
154198
155- if (structuresArray .isEmpty ()) {
156- return new Result (null , 0 );
157- }
158-
159- JsonObject root = new JsonObject ();
160- root .addProperty ("seed" , seed );
161- root .addProperty ("dimension" , dimensionName == null ? Integer .toString (dimension ) : dimensionName );
162- root .addProperty ("center_x" , centerX );
163- root .addProperty ("center_z" , centerZ );
164- root .addProperty ("radius" , radius );
165- root .addProperty ("minecraftVersion" , SharedConstants .getCurrentVersion ().name ());
166- root .add ("structures" , structuresArray );
167-
168- Path lootDir = minecraft .gameDirectory .toPath ().resolve ("SeedMapper" ).resolve ("loot" );
169- Files .createDirectories (lootDir );
170- String serverId = resolveServerId (minecraft );
171- String timestamp = EXPORT_TIMESTAMP .format (LocalDateTime .now ());
172- Path exportFile = lootDir .resolve ("%s_%s-%s.json" .formatted (serverId , Long .toString (seed ), timestamp ));
173- Files .writeString (exportFile , GSON .toJson (root ), StandardCharsets .UTF_8 , StandardOpenOption .CREATE , StandardOpenOption .TRUNCATE_EXISTING );
174- return new Result (exportFile , structuresArray .size ());
199+ return entries ;
175200 }
176201
177202 public record Target (int structureId , BlockPos pos ) {
@@ -180,6 +205,12 @@ public record Target(int structureId, BlockPos pos) {
180205 public record Result (Path path , int entryCount ) {
181206 }
182207
208+ public record LootEntry (String id , String type , String pieceName , BlockPos pos , List <LootItem > items ) {
209+ }
210+
211+ public record LootItem (int slot , int count , String itemId , String displayName , String nbt , List <String > enchantments , List <Integer > enchantmentLevels ) {
212+ }
213+
183214 private static String resolveServerId (Minecraft minecraft ) {
184215 String serverId = "local" ;
185216 try {
0 commit comments