package me.shedaniel.impl; import me.shedaniel.Core; import me.shedaniel.api.IDisplayCategory; import me.shedaniel.api.IREIPlugin; import me.shedaniel.api.IRecipe; import me.shedaniel.api.IRecipeManager; import me.shedaniel.gui.RecipeGui; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.Gui; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.recipe.RecipeManager; import java.awt.*; import java.util.*; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; /** * Created by James on 8/7/2018. */ public class REIRecipeManager implements IRecipeManager { private Map> recipeList; private List displayAdapters; public static RecipeManager recipeManager; private Map, List>> guiExcludeMap; private static REIRecipeManager myInstance; private REIRecipeManager() { recipeList = new HashMap<>(); displayAdapters = new LinkedList<>(); guiExcludeMap = new HashMap<>(); } public Map> getRecipeList() { return recipeList; } public List getDisplayAdapters() { return displayAdapters; } public static REIRecipeManager instance() { if (myInstance == null) { Core.LOGGER.info("REI: Newing me up."); myInstance = new REIRecipeManager(); } return myInstance; } public void addExclusionOnGui(Class guiClass, Function... functions) { List> list = guiExcludeMap.containsKey(guiClass) ? new LinkedList<>(guiExcludeMap.get(guiClass)) : new ArrayList<>(); list.addAll(Arrays.asList(functions)); guiExcludeMap.put(guiClass, list); } public boolean canAddSlot(Class guiClass, Rectangle slotRect) { if (!guiExcludeMap.containsKey(guiClass)) return true; for(Function rectangleBooleanFunction : guiExcludeMap.get(guiClass)) if (!rectangleBooleanFunction.apply(slotRect)) return false; return true; } @Override public void addRecipe(String id, IRecipe recipe) { if (recipeList.containsKey(id)) recipeList.get(id).add(recipe); else { List recipes = new LinkedList<>(); recipeList.put(id, recipes); recipes.add(recipe); } } @Override public void addRecipe(String id, List recipes) { if (recipeList.containsKey(id)) recipeList.get(id).addAll(recipes); else { List newRecipeList = new LinkedList<>(); recipeList.put(id, newRecipeList); newRecipeList.addAll(recipes); } } @Override public void addDisplayAdapter(IDisplayCategory adapter) { displayAdapters.add(adapter); } @Override public Map> getRecipesFor(ItemStack stack) { Map> categories = new HashMap<>(); displayAdapters.forEach(f -> categories.put(f, new LinkedList<>())); for(List value : recipeList.values()) for(IRecipe iRecipe : value) for(Object o : iRecipe.getOutput()) if (o instanceof ItemStack) if (ItemStack.areEqualIgnoreTags(stack, (ItemStack) o)) for(IDisplayCategory iDisplayCategory : categories.keySet()) if (iDisplayCategory.getId() == iRecipe.getId()) { categories.get(iDisplayCategory).add(iRecipe); } categories.keySet().removeIf(f -> categories.get(f).isEmpty()); return categories; } public Map> getUsesFor(ItemStack stack) { Map> categories = new HashMap<>(); displayAdapters.forEach(f -> categories.put(f, new LinkedList<>())); for(List value : recipeList.values()) for(IRecipe iRecipe : value) { boolean found = false; for(Object o : iRecipe.getInput()) { List input = (List) o; for(ItemStack itemStack : input) { if (ItemStack.areEqualIgnoreTags(itemStack, stack)) { for(IDisplayCategory iDisplayCategory : categories.keySet()) if (iDisplayCategory.getId() == iRecipe.getId()) { categories.get(iDisplayCategory).add(iRecipe); found = true; } if (found) break; } } if (found) break; } } categories.keySet().removeIf(f -> categories.get(f).isEmpty()); return categories; } @Deprecated public List findUsageForItems(List types) { List recipes = new ArrayList<>(); types.forEach(item -> { Map> itemUsages = getUsesFor(item); itemUsages.values().forEach(iRecipes -> recipes.addAll(iRecipes)); }); return recipes; } public List findCraftableByItems(List types) { List craftables = new ArrayList<>(); for(List value : recipeList.values()) for(IRecipe iRecipe : value) { int slotsCraftable = 0; List> requiredInput = (List>) iRecipe.getRecipeRequiredInput(); for(List slot : requiredInput) { if (slot.isEmpty()) { slotsCraftable++; continue; } boolean slotDone = false; for(ItemStack possibleType : types) { for(ItemStack slotPossible : slot) if (ItemStack.areEqualIgnoreTags(slotPossible, possibleType)) { slotsCraftable++; slotDone = true; break; } if (slotDone) break; } } if (slotsCraftable == iRecipe.getRecipeRequiredInput().size()) craftables.addAll((List) iRecipe.getOutput()); } return craftables.stream().distinct().collect(Collectors.toList()); } public List getAdatapersForOutput(ItemStack stack) { return null; } public List getAdaptersForOutput(Item item) { return null; } public void RecipesLoaded(RecipeManager manager) { recipeList.clear(); displayAdapters.clear(); REIRecipeManager.instance().recipeManager = manager; Core.getListeners(IREIPlugin.class).forEach(IREIPlugin::registerCategories); Core.getListeners(IREIPlugin.class).forEach(IREIPlugin::registerRecipes); Core.getListeners(IREIPlugin.class).forEach(IREIPlugin::registerSpecialGuiExclusion); } public void displayRecipesFor(ItemStack stack) { Map> recipes = REIRecipeManager.instance().getRecipesFor(stack); if (recipes.isEmpty()) return; RecipeGui gui; if (MinecraftClient.getInstance().currentGui instanceof RecipeGui) gui = new RecipeGui(null, ((RecipeGui) MinecraftClient.getInstance().currentGui).getPrevScreen(), recipes); else gui = new RecipeGui(null, MinecraftClient.getInstance().currentGui, recipes); MinecraftClient.getInstance().openGui(gui); } public void displayUsesFor(ItemStack stack) { Map> recipes = REIRecipeManager.instance().getUsesFor(stack); if (recipes.isEmpty()) return; RecipeGui gui; if (MinecraftClient.getInstance().currentGui instanceof RecipeGui) gui = new RecipeGui(null, ((RecipeGui) MinecraftClient.getInstance().currentGui).getPrevScreen(), recipes); else gui = new RecipeGui(null, MinecraftClient.getInstance().currentGui, recipes); MinecraftClient.getInstance().openGui(gui); } }