Created
September 7, 2020 15:27
-
-
Save marchermans/001bdecfdc71d167750a274c1215c8dc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.ldtteam.aequivaleo.utils; | |
import com.ldtteam.aequivaleo.api.compound.container.ICompoundContainer; | |
import com.ldtteam.aequivaleo.api.recipe.equivalency.IEquivalencyRecipe; | |
import com.ldtteam.aequivaleo.api.recipe.equivalency.ingredient.IRecipeIngredient; | |
import com.ldtteam.aequivaleo.api.recipe.equivalency.ingredient.SimpleIngredientBuilder; | |
import com.ldtteam.aequivaleo.api.util.TriFunction; | |
import com.ldtteam.aequivaleo.compound.container.registry.CompoundContainerFactoryManager; | |
import net.minecraft.item.ItemStack; | |
import net.minecraft.item.crafting.IRecipe; | |
import net.minecraft.item.crafting.Ingredient; | |
import java.util.*; | |
import java.util.function.Function; | |
import java.util.stream.Collectors; | |
import java.util.stream.Stream; | |
public final class RecipeUtils | |
{ | |
private RecipeUtils() | |
{ | |
throw new IllegalStateException("Tried to initialize: RecipeUtils but this is a Utility class."); | |
} | |
public static Stream<IEquivalencyRecipe> getAllVariants( | |
final IRecipe<?> recipe, | |
final TriFunction<SortedSet<IRecipeIngredient>, SortedSet<ICompoundContainer<?>>, SortedSet<ICompoundContainer<?>>, IEquivalencyRecipe> recipeFactory | |
) | |
{ | |
if (recipe.isDynamic()) | |
{ | |
return Stream.empty(); | |
} | |
if (recipe.getRecipeOutput().isEmpty()) | |
{ | |
return Stream.empty(); | |
} | |
final ICompoundContainer<?> result = CompoundContainerFactoryManager.getInstance().wrapInContainer(recipe.getRecipeOutput(), recipe.getRecipeOutput().getCount()); | |
final SortedSet<ICompoundContainer<?>> resultSet = new TreeSet<>(); | |
resultSet.add(result); | |
return getAllInputVariants(recipe.getIngredients(), true) | |
.map(iRecipeIngredients -> { | |
final SortedSet<ICompoundContainer<?>> containers = | |
mapStacks( | |
iRecipeIngredients.stream() | |
.map(iRecipeIngredient -> iRecipeIngredient.getCandidates() | |
.stream() | |
.map(ICompoundContainer::getContents) | |
.filter(ItemStack.class::isInstance) | |
.map(ItemStack.class::cast) | |
.filter(stack -> !stack.isEmpty()) | |
.map(ItemStack::getContainerItem) | |
.filter(stack -> !stack.isEmpty()) | |
.collect(Collectors.toList()) | |
) | |
.filter(stacks -> !stacks.isEmpty()) | |
.findAny() | |
.orElse(Collections.emptyList()) | |
); | |
return recipeFactory.apply(iRecipeIngredients, containers, resultSet); | |
}); | |
} | |
public static Stream<SortedSet<IRecipeIngredient>> getAllInputVariants(final List<Ingredient> mcIngredients) | |
{ | |
return getAllInputVariants(mcIngredients, true); | |
} | |
public static Stream<SortedSet<IRecipeIngredient>> getAllInputVariants(final List<Ingredient> mcIngredients, final boolean checkSimple) | |
{ | |
if (mcIngredients.isEmpty() || (checkSimple && mcIngredients.stream().anyMatch(ingredient -> !ingredient.isSimple()))) | |
{ | |
return Stream.empty(); | |
} | |
if (mcIngredients.size() == 1) | |
{ | |
return getAllVariantsFromSimpleIngredient(mcIngredients.get(0)) | |
.map(iRecipeIngredient -> { | |
final SortedSet<IRecipeIngredient> ingredients = new TreeSet<>(); | |
ingredients.add(iRecipeIngredient); | |
return ingredients; | |
}); | |
} | |
final Ingredient target = mcIngredients.get(0); | |
final List<Ingredient> ingredients = new ArrayList<>(mcIngredients); | |
ingredients.remove(0); | |
final Stream<IRecipeIngredient> targetIngredients = getAllVariantsFromSimpleIngredient(target); | |
final Set<IRecipeIngredient> targets = targetIngredients.collect(Collectors.toCollection(TreeSet::new)); | |
return getAllInputVariants(ingredients, false) | |
.flatMap(subRecpIng -> targets.stream() | |
.map(nextIng -> { | |
subRecpIng.add(nextIng); | |
return subRecpIng; | |
})); | |
} | |
private static Stream<IRecipeIngredient> getAllVariantsFromSimpleIngredient(final Ingredient ingredient) { | |
return Arrays.stream( | |
ingredient.getMatchingStacks() | |
).collect(Collectors.groupingBy(stack -> new ItemStackEqualityWrapper(stack.getContainerItem()))) | |
.values() | |
.stream() | |
.map(RecipeUtils::mapStacks) | |
.map(stacks -> new SimpleIngredientBuilder().from(stacks).withCount(1d).createIngredient()); | |
} | |
private static SortedSet<ICompoundContainer<?>> mapStacks(final List<ItemStack> stacks) { | |
final SortedSet<ICompoundContainer<?>> result = | |
stacks.stream().map(stack -> CompoundContainerFactoryManager.getInstance().wrapInContainer(stack, stack.getCount())).collect(Collectors.toCollection(TreeSet::new)); | |
return result; | |
} | |
private static final class RecipeData | |
{ | |
private final SortedSet<IRecipeIngredient> ingredients; | |
private final SortedSet<ICompoundContainer<?>> requiredKnownOutputs; | |
private final SortedSet<ICompoundContainer<?>> outputs; | |
private RecipeData( | |
final SortedSet<IRecipeIngredient> ingredients, | |
final SortedSet<ICompoundContainer<?>> requiredKnownOutputs, final SortedSet<ICompoundContainer<?>> outputs) | |
{ | |
this.ingredients = ingredients; | |
this.requiredKnownOutputs = requiredKnownOutputs; | |
this.outputs = outputs; | |
} | |
public SortedSet<IRecipeIngredient> getIngredients() | |
{ | |
return ingredients; | |
} | |
public SortedSet<ICompoundContainer<?>> getRequiredKnownOutputs() | |
{ | |
return requiredKnownOutputs; | |
} | |
public SortedSet<ICompoundContainer<?>> getOutputs() | |
{ | |
return outputs; | |
} | |
} | |
private static final class ItemStackEqualityWrapper | |
{ | |
private final ItemStack stack; | |
private ItemStackEqualityWrapper(final ItemStack stack) {this.stack = stack;} | |
@Override | |
public int hashCode() | |
{ | |
return Objects.hash( | |
stack.getItem().getRegistryName(), | |
stack.getDamage(), | |
stack.getOrCreateTag() | |
); | |
} | |
@Override | |
public boolean equals(final Object o) | |
{ | |
if (!(o instanceof ItemStackEqualityWrapper)) | |
{ | |
return false; | |
} | |
final ItemStackEqualityWrapper other = (ItemStackEqualityWrapper) o; | |
return Objects.equals( | |
stack.getItem().getRegistryName(), | |
other.stack.getItem().getRegistryName() | |
) && | |
Objects.equals( | |
stack.getDamage(), | |
other.stack.getDamage() | |
) && | |
Objects.equals( | |
stack.getOrCreateTag(), | |
other.stack.getOrCreateTag() | |
); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment