--- a/net/minecraft/world/item/crafting/CraftingManager.java +++ b/net/minecraft/world/item/crafting/CraftingManager.java @@ -34,6 +34,11 @@ import net.minecraft.world.level.World; import org.slf4j.Logger; +// CraftBukkit start +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Maps; +// CraftBukkit end + public class CraftingManager extends ResourceDataJson { private static final Gson GSON = (new GsonBuilder()).setPrettyPrinting().disableHtmlEscaping().create(); @@ -70,19 +75,39 @@ } } - this.byType = builder.build(); - this.byName = com_google_common_collect_immutablemap_builder.build(); + // CraftBukkit start - mutable + this.byType = LinkedHashMultimap.create(builder.build()); + this.byName = Maps.newHashMap(com_google_common_collect_immutablemap_builder.build()); + // CraftBukkit end CraftingManager.LOGGER.info("Loaded {} recipes", this.byType.size()); } + // CraftBukkit start + public void addRecipe(RecipeHolder irecipe) { + Collection> map = this.byType.get(irecipe.value().getType()); // CraftBukkit + + if (byName.containsKey(irecipe.id())) { + throw new IllegalStateException("Duplicate recipe ignored with ID " + irecipe.id()); + } else { + map.add(irecipe); + byName.put(irecipe.id(), irecipe); + } + } + // CraftBukkit end + public boolean hadErrorsLoading() { return this.hasErrors; } public > Optional> getRecipeFor(Recipes recipes, C c0, World world) { - return this.byType(recipes).stream().filter((recipeholder) -> { + // CraftBukkit start + List> list = this.byType(recipes).stream().filter((recipeholder) -> { return recipeholder.value().matches(c0, world); - }).findFirst(); + }).toList(); + Optional> recipe = (list.isEmpty()) ? Optional.empty() : Optional.of(list.getLast()); // CraftBukkit - SPIGOT-4638: last recipe gets priority + c0.setCurrentRecipe(recipe.orElse(null)); // CraftBukkit - Clear recipe when no recipe is found + return recipe; + // CraftBukkit end } public > Optional> getRecipeFor(Recipes recipes, C c0, World world, @Nullable MinecraftKey minecraftkey) { @@ -94,9 +119,14 @@ } } - return this.byType(recipes).stream().filter((recipeholder1) -> { + // CraftBukkit start + List> list = this.byType(recipes).stream().filter((recipeholder1) -> { return recipeholder1.value().matches(c0, world); - }).findFirst(); + }).toList(); + Optional> recipe = (list.isEmpty()) ? Optional.empty() : Optional.of(list.getLast()); // CraftBukkit - SPIGOT-4638: last recipe gets priority + c0.setCurrentRecipe(recipe.orElse(null)); // CraftBukkit - Clear recipe when no recipe is found + return recipe; + // CraftBukkit end } public > List> getAllRecipesFor(Recipes recipes) { @@ -112,7 +142,7 @@ } private > Collection> byType(Recipes recipes) { - return this.byType.get(recipes); + return (Collection) this.byType.get(recipes); // CraftBukkit - decompile error } public > NonNullList getRemainingItemsFor(Recipes recipes, C c0, World world) { @@ -139,7 +169,7 @@ private > RecipeHolder byKeyTyped(Recipes recipes, MinecraftKey minecraftkey) { RecipeHolder recipeholder = (RecipeHolder) this.byName.get(minecraftkey); - return recipeholder != null && recipeholder.value().getType().equals(recipes) ? recipeholder : null; + return recipeholder != null && recipeholder.value().getType().equals(recipes) ? (RecipeHolder) recipeholder : null; // CraftBukkit - decompile error } public Collection> getOrderedRecipes() { @@ -175,10 +205,31 @@ com_google_common_collect_immutablemap_builder.put(recipeholder.id(), recipeholder); } - this.byType = builder.build(); - this.byName = com_google_common_collect_immutablemap_builder.build(); + // CraftBukkit start - mutable + this.byType = LinkedHashMultimap.create(builder.build()); + this.byName = Maps.newHashMap(com_google_common_collect_immutablemap_builder.build()); + // CraftBukkit end } + // CraftBukkit start + public boolean removeRecipe(MinecraftKey mcKey) { + Iterator> iter = byType.values().iterator(); + while (iter.hasNext()) { + RecipeHolder recipe = iter.next(); + if (recipe.id().equals(mcKey)) { + iter.remove(); + } + } + + return byName.remove(mcKey) != null; + } + + public void clearRecipes() { + this.byType = LinkedHashMultimap.create(); + this.byName = Maps.newHashMap(); + } + // CraftBukkit end + public static > CraftingManager.a createCheck(final Recipes recipes) { return new CraftingManager.a() { @Nullable