package net.minecraft.world.item.crafting; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.ImmutableMultimap.Builder; import java.util.Collection; import java.util.Map; import java.util.stream.Stream; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.Level; import org.jspecify.annotations.Nullable; public class RecipeMap { public static final RecipeMap EMPTY = new RecipeMap(ImmutableMultimap.of(), Map.of()); private final Multimap, RecipeHolder> byType; private final Map>, RecipeHolder> byKey; private RecipeMap(final Multimap, RecipeHolder> byType, final Map>, RecipeHolder> byKey) { this.byType = byType; this.byKey = byKey; } public static RecipeMap create(final Iterable> recipes) { Builder, RecipeHolder> byType = ImmutableMultimap.builder(); com.google.common.collect.ImmutableMap.Builder>, RecipeHolder> byKey = ImmutableMap.builder(); for (RecipeHolder recipe : recipes) { byType.put(recipe.value().getType(), recipe); byKey.put(recipe.id(), recipe); } return new RecipeMap(byType.build(), byKey.build()); } public > Collection> byType(final RecipeType type) { return (Collection>)this.byType.get(type); } public Collection> values() { return this.byKey.values(); } @Nullable public RecipeHolder byKey(final ResourceKey> recipeId) { return (RecipeHolder)this.byKey.get(recipeId); } public > Stream> getRecipesFor(final RecipeType type, final I container, final Level level) { return container.isEmpty() ? Stream.empty() : this.byType(type).stream().filter(r -> r.value().matches(container, level)); } }