diff --git a/dependencies.gradle b/dependencies.gradle index 344f1b3a..8dc68525 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -21,5 +21,6 @@ dependencies { compileOnly('com.github.GTNewHorizons:ThaumicEnergistics:1.3.19-GTNH:dev') {transitive = false} compileOnly("com.github.GTNewHorizons:EnderIO:2.3.1.29:dev") {transitive = false} + runtime("com.github.GTNewHorizons:Baubles:1.0.1.14:dev") } diff --git a/src/main/java/com/glodblock/github/nei/recipes/DefaultExtractorLoader.java b/src/main/java/com/glodblock/github/nei/recipes/DefaultExtractorLoader.java index 9b0a1540..858b0349 100644 --- a/src/main/java/com/glodblock/github/nei/recipes/DefaultExtractorLoader.java +++ b/src/main/java/com/glodblock/github/nei/recipes/DefaultExtractorLoader.java @@ -47,6 +47,19 @@ public class DefaultExtractorLoader implements Runnable { FluidRecipe.addRecipeMap(null, new ForestryRecipeExtractor(new NEIHandlerStill())); } + if (ModAndClassUtil.IC2) { + FluidRecipe.addRecipeMap("blastfurnace", new IndustrialCraftRecipeExtractor()); + FluidRecipe.addRecipeMap("BlockCutter", new IndustrialCraftRecipeExtractor()); + FluidRecipe.addRecipeMap("centrifuge", new IndustrialCraftRecipeExtractor()); + FluidRecipe.addRecipeMap("compressor", new IndustrialCraftRecipeExtractor()); + FluidRecipe.addRecipeMap("extractor", new IndustrialCraftRecipeExtractor()); + FluidRecipe.addRecipeMap("fluidcanner", new IndustrialCraftRecipeExtractor()); + FluidRecipe.addRecipeMap("macerator", new IndustrialCraftRecipeExtractor()); + FluidRecipe.addRecipeMap("metalformer", new IndustrialCraftRecipeExtractor()); + FluidRecipe.addRecipeMap("oreWashing", new IndustrialCraftRecipeExtractor()); + FluidRecipe.addRecipeMap("solidcanner", new IndustrialCraftRecipeExtractor()); + } + } } diff --git a/src/main/java/com/glodblock/github/nei/recipes/extractor/IndustrialCraftRecipeExtractor.java b/src/main/java/com/glodblock/github/nei/recipes/extractor/IndustrialCraftRecipeExtractor.java new file mode 100644 index 00000000..88343e44 --- /dev/null +++ b/src/main/java/com/glodblock/github/nei/recipes/extractor/IndustrialCraftRecipeExtractor.java @@ -0,0 +1,114 @@ +package com.glodblock.github.nei.recipes.extractor; + +import codechicken.nei.PositionedStack; +import codechicken.nei.recipe.IRecipeHandler; +import com.glodblock.github.nei.object.IRecipeExtractor; +import com.glodblock.github.nei.object.OrderStack; +import com.glodblock.github.util.Ae2Reflect; +import ic2.neiIntegration.core.recipehandler.FluidCannerRecipeHandler; +import ic2.neiIntegration.core.recipehandler.OreWashingRecipeHandler; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class IndustrialCraftRecipeExtractor implements IRecipeExtractor { + + @Override + public List> getInputIngredients(List rawInputs) { + List> tmp = new LinkedList<>(); + for (int i = 0; i < rawInputs.size(); i ++) { + if (rawInputs.get(i) == null) continue; + tmp.add(OrderStack.pack(rawInputs.get(i), i)); + } + return tmp; + } + + @Override + public List> getOutputIngredients(List rawOutputs) { + List> tmp = new LinkedList<>(); + for (int i = 0; i < rawOutputs.size(); i ++) { + if (rawOutputs.get(i) == null) continue; + tmp.add(OrderStack.pack(rawOutputs.get(i), i)); + } + return tmp; + } + + @Override + public List> getInputIngredients(List rawInputs, IRecipeHandler recipe, int index) { + List> stacks = new LinkedList<>(); + + if (recipe instanceof FluidCannerRecipeHandler) { + FluidCannerRecipeHandler.CachedFluidCannerRecipe cachedRecipe = (FluidCannerRecipeHandler.CachedFluidCannerRecipe) ((FluidCannerRecipeHandler) recipe).arecipes.get(index); + FluidStack input = ReflectIC2.getInputFluid(cachedRecipe); + PositionedStack add = rawInputs.size() > 1 ? rawInputs.get(1) : null; + stacks.add(OrderStack.pack(add, 0)); + stacks.add(new OrderStack<>(input, 1)); + } + else if (recipe instanceof OreWashingRecipeHandler) { + stacks = getInputIngredients(rawInputs); + int water = ReflectIC2.getOreWasherWater((OreWashingRecipeHandler) recipe, index); + stacks.add(new OrderStack<>(new FluidStack(FluidRegistry.WATER, water), stacks.size())); + } else { + stacks = getInputIngredients(rawInputs); + } + + return stacks.stream().filter(Objects::nonNull).collect(Collectors.toList()); + } + + @Override + public List> getOutputIngredients(List rawOutputs, IRecipeHandler recipe, int index) { + List> stacks = new LinkedList<>(); + + if (recipe instanceof FluidCannerRecipeHandler) { + FluidCannerRecipeHandler.CachedFluidCannerRecipe cachedRecipe = (FluidCannerRecipeHandler.CachedFluidCannerRecipe) ((FluidCannerRecipeHandler) recipe).arecipes.get(index); + FluidStack output = ReflectIC2.getOutputFluid(cachedRecipe); + stacks.add(new OrderStack<>(output, 0)); + } else { + stacks = getOutputIngredients(rawOutputs); + } + + return stacks.stream().filter(Objects::nonNull).collect(Collectors.toList()); + } + + private static class ReflectIC2 { + + private final static Field inputsF; + private final static Field resultF; + + private final static Method oreWasherWater; + + static { + try { + inputsF = Ae2Reflect.reflectField(FluidCannerRecipeHandler.CachedFluidCannerRecipe.class, "fluidInput"); + resultF = Ae2Reflect.reflectField(FluidCannerRecipeHandler.CachedFluidCannerRecipe.class, "fluidOutput"); + oreWasherWater = Ae2Reflect.reflectMethod(OreWashingRecipeHandler.class, "getreqWater", int.class); + } catch (NoSuchFieldException | NoSuchMethodException e) { + throw new IllegalStateException("Failed to initialize IC2 reflection hacks!", e); + } + } + + private static FluidStack getInputFluid(FluidCannerRecipeHandler.CachedFluidCannerRecipe recipe) { + return Ae2Reflect.readField(recipe, inputsF); + } + + private static FluidStack getOutputFluid(FluidCannerRecipeHandler.CachedFluidCannerRecipe recipe) { + return Ae2Reflect.readField(recipe, resultF); + } + + private static int getOreWasherWater(OreWashingRecipeHandler recipeHandler, int index) { + try { + return (int) oreWasherWater.invoke(recipeHandler, index); + } catch (Exception e) { + throw new IllegalStateException("Failed to invoke method: " + oreWasherWater, e); + } + } + + } + +} diff --git a/src/main/java/com/glodblock/github/util/ModAndClassUtil.java b/src/main/java/com/glodblock/github/util/ModAndClassUtil.java index abb57118..ef52c355 100644 --- a/src/main/java/com/glodblock/github/util/ModAndClassUtil.java +++ b/src/main/java/com/glodblock/github/util/ModAndClassUtil.java @@ -20,6 +20,7 @@ public final class ModAndClassUtil { public static boolean OC = false; public static boolean ThE = false; public static boolean WCT = false; + public static boolean IC2 = false; public static boolean isDoubleButton; public static boolean isSaveText; @@ -112,6 +113,8 @@ public final class ModAndClassUtil { ThE = true; if (Loader.isModLoaded("ae2wct")) WCT = true; + if (Loader.isModLoaded("IC2")) + IC2 = true; } }