|
4 | 4 | import java.util.List; |
5 | 5 | import java.util.Map; |
6 | 6 | import java.util.Optional; |
7 | | -import java.util.stream.Collectors; |
8 | 7 |
|
9 | 8 | import com.tcm.MineTale.MineTale; |
10 | 9 | import com.tcm.MineTale.block.workbenches.menu.AbstractWorkbenchContainerMenu; |
|
26 | 25 | import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; |
27 | 26 | import net.minecraft.client.gui.screens.recipebook.RecipeCollection; |
28 | 27 | import net.minecraft.client.renderer.RenderPipelines; |
29 | | -import net.minecraft.core.HolderSet; |
| 28 | +import net.minecraft.core.Holder; |
30 | 29 | import net.minecraft.resources.Identifier; |
31 | 30 | import net.minecraft.world.entity.player.Inventory; |
32 | 31 | import net.minecraft.world.entity.player.Player; |
@@ -222,32 +221,31 @@ private boolean canCraft(Player player, RecipeDisplayEntry entry, int craftCount |
222 | 221 | Optional<List<Ingredient>> reqs = entry.craftingRequirements(); |
223 | 222 | if (reqs.isEmpty()) return false; |
224 | 223 |
|
225 | | - // 1. Group ingredients by their underlying Item HolderSet. |
226 | | - // Since Ingredient doesn't override hashCode, we use the values field directly |
227 | | - // or use a List of Holders as the key for stable hashing. |
228 | | - Map<HolderSet<Item>, Integer> aggregatedRequirements = new HashMap<>(); |
229 | | - |
230 | | - // Helper map to get back to an Ingredient object for the final check |
231 | | - Map<HolderSet<Item>, Ingredient> holderToIngredient = new HashMap<>(); |
| 224 | + // 1. Group ingredients by their underlying Item Holders. |
| 225 | + // Using List<Holder<Item>> as the key ensures structural equality (content-based hashing). |
| 226 | + Map<List<Holder<Item>>, Integer> aggregatedRequirements = new HashMap<>(); |
| 227 | + Map<List<Holder<Item>>, Ingredient> holderToIngredient = new HashMap<>(); |
232 | 228 |
|
233 | 229 | for (Ingredient ing : reqs.get()) { |
234 | | - // Accessing the 'values' via a custom accessor or reflection if private, |
235 | | - // but based on your source, we can use the Ingredient object itself |
236 | | - // IF we use a helper that handles the hashing correctly. |
237 | | - |
238 | | - // Strategy: Use the stream of holders as a List key (Lists have stable hashcodes) |
| 230 | + // Collect holders into a List to get a stable hashCode() and equals() |
239 | 231 | @SuppressWarnings("deprecation") |
240 | | - HolderSet<Item> key = ing.items().collect(Collectors.collectingAndThen(Collectors.toList(), HolderSet::direct)); |
241 | | - |
| 232 | + List<Holder<Item>> key = ing.items().toList(); |
| 233 | + |
| 234 | + // Aggregate the counts (how many of this specific ingredient set are required) |
242 | 235 | aggregatedRequirements.put(key, aggregatedRequirements.getOrDefault(key, 0) + 1); |
| 236 | + |
| 237 | + // Map the list back to the original ingredient for use in hasIngredientAmount |
243 | 238 | holderToIngredient.putIfAbsent(key, ing); |
244 | 239 | } |
245 | 240 |
|
246 | | - // 2. Check the player's inventory |
| 241 | + // 2. Check the player's inventory against the aggregated totals |
247 | 242 | Inventory inv = player.getInventory(); |
248 | | - for (Map.Entry<HolderSet<Item>, Integer> entryReq : aggregatedRequirements.entrySet()) { |
| 243 | + for (Map.Entry<List<Holder<Item>>, Integer> entryReq : aggregatedRequirements.entrySet()) { |
| 244 | + List<Holder<Item>> key = entryReq.getKey(); |
249 | 245 | int totalNeeded = entryReq.getValue() * craftCount; |
250 | | - Ingredient originalIng = holderToIngredient.get(entryReq.getKey()); |
| 246 | + |
| 247 | + // Retrieve the original Ingredient object associated with this list of holders |
| 248 | + Ingredient originalIng = holderToIngredient.get(key); |
251 | 249 |
|
252 | 250 | if (!hasIngredientAmount(inv, originalIng, totalNeeded)) { |
253 | 251 | return false; |
|
0 commit comments