diff options
Diffstat (limited to 'src/main/java/gregtech/api/recipe/maps')
20 files changed, 1467 insertions, 0 deletions
diff --git a/src/main/java/gregtech/api/recipe/maps/AssemblerBackend.java b/src/main/java/gregtech/api/recipe/maps/AssemblerBackend.java new file mode 100644 index 0000000000..cfa25e9fe2 --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/AssemblerBackend.java @@ -0,0 +1,35 @@ +package gregtech.api.recipe.maps; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.api.enums.ItemList; +import gregtech.api.recipe.RecipeMapBackend; +import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.MethodsReturnNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class AssemblerBackend extends RecipeMapBackend { + + public AssemblerBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { + super(propertiesBuilder); + } + + @Override + protected GT_Recipe modifyFoundRecipe(GT_Recipe recipe, ItemStack[] items, FluidStack[] fluids, + @Nullable ItemStack specialSlot) { + for (ItemStack item : items) { + if (ItemList.Paper_Printed_Pages.isStackEqual(item, false, true)) { + recipe = recipe.copy(); + recipe.mCanBeBuffered = false; + recipe.mOutputs[0].setTagCompound(item.getTagCompound()); + } + } + return recipe; + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/AssemblyLineFrontend.java b/src/main/java/gregtech/api/recipe/maps/AssemblyLineFrontend.java new file mode 100644 index 0000000000..3d56c96b82 --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/AssemblyLineFrontend.java @@ -0,0 +1,76 @@ +package gregtech.api.recipe.maps; + +import java.util.Collections; +import java.util.List; +import java.util.function.Supplier; + +import javax.annotation.ParametersAreNonnullByDefault; + +import com.gtnewhorizons.modularui.api.math.Pos2d; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.common.widget.ProgressBar; + +import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.recipe.BasicUIPropertiesBuilder; +import gregtech.api.recipe.NEIRecipePropertiesBuilder; +import gregtech.api.recipe.RecipeMapFrontend; +import gregtech.api.util.MethodsReturnNonnullByDefault; +import gregtech.common.gui.modularui.UIHelper; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class AssemblyLineFrontend extends RecipeMapFrontend { + + public AssemblyLineFrontend(BasicUIPropertiesBuilder uiPropertiesBuilder, + NEIRecipePropertiesBuilder neiPropertiesBuilder) { + super(uiPropertiesBuilder, neiPropertiesBuilder); + } + + @Override + public List<Pos2d> getItemInputPositions(int itemInputCount) { + return UIHelper.getGridPositions(itemInputCount, 16, 8, 4); + } + + @Override + public List<Pos2d> getItemOutputPositions(int itemOutputCount) { + return Collections.singletonList(new Pos2d(142, 8)); + } + + @Override + public Pos2d getSpecialItemPosition() { + return new Pos2d(142, 44); + } + + @Override + public List<Pos2d> getFluidInputPositions(int fluidInputCount) { + return UIHelper.getGridPositions(fluidInputCount, 106, 8, 1); + } + + @Override + public void addProgressBar(ModularWindow.Builder builder, Supplier<Float> progressSupplier, Pos2d windowOffset) { + int bar1Width = 17; + int bar2Width = 18; + List<Supplier<Float>> splitProgress = splitProgress(progressSupplier, bar1Width, bar2Width); + builder.widget( + new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_1, bar1Width) + .setDirection(ProgressBar.Direction.RIGHT) + .setProgress(splitProgress.get(0)) + .setSynced(false, false) + .setPos(new Pos2d(88, 8).add(windowOffset)) + .setSize(bar1Width, 72)); + builder.widget( + new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_2, bar2Width) + .setDirection(ProgressBar.Direction.RIGHT) + .setProgress(splitProgress.get(1)) + .setSynced(false, false) + .setPos(new Pos2d(124, 8).add(windowOffset)) + .setSize(bar2Width, 72)); + builder.widget( + new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_3, 18) + .setDirection(ProgressBar.Direction.UP) + .setProgress(progressSupplier) + .setSynced(false, false) + .setPos(new Pos2d(146, 26).add(windowOffset)) + .setSize(10, 18)); + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/DistillationTowerFrontend.java b/src/main/java/gregtech/api/recipe/maps/DistillationTowerFrontend.java new file mode 100644 index 0000000000..b061d10d55 --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/DistillationTowerFrontend.java @@ -0,0 +1,38 @@ +package gregtech.api.recipe.maps; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.annotation.ParametersAreNonnullByDefault; + +import com.gtnewhorizons.modularui.api.math.Pos2d; + +import gregtech.api.recipe.BasicUIPropertiesBuilder; +import gregtech.api.recipe.NEIRecipePropertiesBuilder; +import gregtech.api.recipe.RecipeMapFrontend; +import gregtech.api.util.MethodsReturnNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class DistillationTowerFrontend extends RecipeMapFrontend { + + public DistillationTowerFrontend(BasicUIPropertiesBuilder uiPropertiesBuilder, + NEIRecipePropertiesBuilder neiPropertiesBuilder) { + super(uiPropertiesBuilder, neiPropertiesBuilder); + } + + @Override + public List<Pos2d> getItemOutputPositions(int itemOutputCount) { + return Collections.singletonList(new Pos2d(106, 62)); + } + + @Override + public List<Pos2d> getFluidOutputPositions(int fluidOutputCount) { + List<Pos2d> results = new ArrayList<>(); + for (int i = 1; i < fluidOutputCount + 1; i++) { + results.add(new Pos2d(106 + (i % 3) * 18, 62 - (i / 3) * 18)); + } + return results; + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/FluidCannerBackend.java b/src/main/java/gregtech/api/recipe/maps/FluidCannerBackend.java new file mode 100644 index 0000000000..e5681f59aa --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/FluidCannerBackend.java @@ -0,0 +1,73 @@ +package gregtech.api.recipe.maps; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidContainerItem; + +import gregtech.api.enums.GT_Values; +import gregtech.api.recipe.RecipeMapBackend; +import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GT_Utility; +import gregtech.api.util.MethodsReturnNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class FluidCannerBackend extends RecipeMapBackend { + + public FluidCannerBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { + super(propertiesBuilder); + } + + @Override + protected GT_Recipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { + if (items.length == 0 || items[0] == null) { + return null; + } + + if (fluids.length > 0 && fluids[0] != null) { + ItemStack filledItem = GT_Utility.fillFluidContainer(fluids[0], items[0], false, true); + FluidStack fluidToTake = GT_Utility.getFluidForFilledItem(filledItem, true); + if (fluidToTake != null) { + return GT_Values.RA.stdBuilder() + .itemInputs(GT_Utility.copyAmount(1, items[0])) + .itemOutputs(filledItem) + .fluidInputs(fluidToTake) + .duration(Math.max(fluidToTake.amount / 64, 16)) + .eut(1) + .noOptimize() + .noBuffer() + .build() + .orElse(null); + } + } + FluidStack drainedFluid = GT_Utility.getFluidForFilledItem(items[0], true); + if (drainedFluid != null) { + return GT_Values.RA.stdBuilder() + .itemInputs(GT_Utility.copyAmount(1, items[0])) + .itemOutputs(GT_Utility.getContainerItem(items[0], true)) + .fluidOutputs(drainedFluid) + .duration(Math.max(drainedFluid.amount / 64, 16)) + .eut(1) + .noBuffer() + .build() + .orElse(null); + } + return null; + } + + @Override + public boolean containsInput(ItemStack item) { + return super.containsInput(item) || (item.getItem() instanceof IFluidContainerItem + && ((IFluidContainerItem) item.getItem()).getCapacity(item) > 0); + } + + @Override + public boolean containsInput(Fluid fluid) { + return true; + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/FluidOnlyFrontend.java b/src/main/java/gregtech/api/recipe/maps/FluidOnlyFrontend.java new file mode 100644 index 0000000000..8b37f6388c --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/FluidOnlyFrontend.java @@ -0,0 +1,33 @@ +package gregtech.api.recipe.maps; + +import java.util.List; + +import com.gtnewhorizons.modularui.api.math.Pos2d; + +import gregtech.api.recipe.BasicUIPropertiesBuilder; +import gregtech.api.recipe.NEIRecipePropertiesBuilder; +import gregtech.api.recipe.RecipeMapFrontend; +import gregtech.api.util.MethodsReturnNonnullByDefault; +import gregtech.common.gui.modularui.UIHelper; + +/** + * Display fluids where normally items are placed on NEI. + */ +@MethodsReturnNonnullByDefault +public class FluidOnlyFrontend extends RecipeMapFrontend { + + public FluidOnlyFrontend(BasicUIPropertiesBuilder uiPropertiesBuilder, + NEIRecipePropertiesBuilder neiPropertiesBuilder) { + super(uiPropertiesBuilder, neiPropertiesBuilder); + } + + @Override + public List<Pos2d> getFluidInputPositions(int fluidInputCount) { + return UIHelper.getItemInputPositions(fluidInputCount); + } + + @Override + public List<Pos2d> getFluidOutputPositions(int fluidOutputCount) { + return UIHelper.getItemOutputPositions(fluidOutputCount); + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/FormingPressBackend.java b/src/main/java/gregtech/api/recipe/maps/FormingPressBackend.java new file mode 100644 index 0000000000..ce3ea3e89c --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/FormingPressBackend.java @@ -0,0 +1,92 @@ +package gregtech.api.recipe.maps; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.api.enums.GT_Values; +import gregtech.api.enums.ItemList; +import gregtech.api.recipe.RecipeMapBackend; +import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GT_Utility; +import gregtech.api.util.MethodsReturnNonnullByDefault; + +/** + * Special Class for Forming Press handling. + */ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class FormingPressBackend extends RecipeMapBackend { + + public FormingPressBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { + super(propertiesBuilder); + } + + @Override + protected GT_Recipe modifyFoundRecipe(GT_Recipe recipe, ItemStack[] items, FluidStack[] fluids, + @Nullable ItemStack specialSlot) { + for (ItemStack mold : items) { + if (ItemList.Shape_Mold_Credit.isStackEqual(mold, false, true)) { + NBTTagCompound nbt = mold.getTagCompound(); + if (nbt == null) nbt = new NBTTagCompound(); + if (!nbt.hasKey("credit_security_id")) nbt.setLong("credit_security_id", System.nanoTime()); + mold.setTagCompound(nbt); + + recipe = recipe.copy(); + recipe.mCanBeBuffered = false; + recipe.mOutputs[0].setTagCompound(nbt); + return recipe; + } + } + return recipe; + } + + @Override + protected GT_Recipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { + if (items.length < 2) { + return null; + } + return findRenamingRecipe(items); + } + + @Nullable + private GT_Recipe findRenamingRecipe(ItemStack[] inputs) { + ItemStack mold = findNameMoldIndex(inputs); + if (mold == null) return null; + ItemStack input = findStackToRename(inputs, mold); + if (input == null) return null; + ItemStack output = GT_Utility.copyAmount(1, input); + if (output == null) return null; + output.setStackDisplayName(mold.getDisplayName()); + return GT_Values.RA.stdBuilder() + .itemInputs(GT_Utility.copyAmount(0, mold), GT_Utility.copyAmount(1, input)) + .itemOutputs(output) + .duration(128) + .eut(8) + .noBuffer() + .nbtSensitive() + .build() + .orElse(null); + } + + @Nullable + private ItemStack findNameMoldIndex(ItemStack[] inputs) { + for (ItemStack stack : inputs) { + if (ItemList.Shape_Mold_Name.isStackEqual(stack, false, true)) return stack; + } + return null; + } + + @Nullable + private ItemStack findStackToRename(ItemStack[] inputs, ItemStack mold) { + for (ItemStack stack : inputs) { + if (stack == mold || stack == null) continue; + return stack; + } + return null; + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/FuelBackend.java b/src/main/java/gregtech/api/recipe/maps/FuelBackend.java new file mode 100644 index 0000000000..49c989e174 --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/FuelBackend.java @@ -0,0 +1,75 @@ +package gregtech.api.recipe.maps; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.api.recipe.RecipeMapBackend; +import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GT_RecipeBuilder; +import gregtech.api.util.GT_Utility; +import gregtech.api.util.MethodsReturnNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class FuelBackend extends RecipeMapBackend { + + private final Map<String, GT_Recipe> recipesByFluidInput = new HashMap<>(); + + public FuelBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { + super(propertiesBuilder.disableOptimize()); + } + + @Override + protected Collection<GT_Recipe> doAdd(GT_RecipeBuilder builder) { + if (builder.getDuration() == -1) { + builder.duration(0); + } + if (builder.getEUt() == -1) { + builder.eut(0); + } + return super.doAdd(builder); + } + + @Override + public GT_Recipe compileRecipe(GT_Recipe recipe) { + super.compileRecipe(recipe); + if (recipe.mInputs != null && GT_Utility.getNonnullElementCount(recipe.mInputs) == 1 + && (recipe.mFluidInputs == null || GT_Utility.getNonnullElementCount(recipe.mFluidInputs) == 0)) { + FluidStack fluidStack = GT_Utility.getFluidForFilledItem(recipe.mInputs[0], true); + if (fluidStack != null) { + fluidStack.amount = 0; + recipesByFluidInput.put( + fluidStack.getFluid() + .getName(), + recipe); + } + } else if ((recipe.mInputs == null || GT_Utility.getNonnullElementCount(recipe.mInputs) == 0) + && recipe.mFluidInputs != null + && GT_Utility.getNonnullElementCount(recipe.mFluidInputs) >= 1 + && recipe.mFluidInputs[0] != null) { + recipesByFluidInput.put( + recipe.mFluidInputs[0].getFluid() + .getName(), + recipe); + } + return recipe; + } + + @Nullable + public GT_Recipe findFuel(FluidStack fluidStack) { + return findFuel(fluidStack.getFluid()); + } + + @Nullable + public GT_Recipe findFuel(Fluid fluid) { + return recipesByFluidInput.get(fluid.getName()); + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/FurnaceBackend.java b/src/main/java/gregtech/api/recipe/maps/FurnaceBackend.java new file mode 100644 index 0000000000..c4095eeb4e --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/FurnaceBackend.java @@ -0,0 +1,52 @@ +package gregtech.api.recipe.maps; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.api.enums.GT_Values; +import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; +import gregtech.api.util.GT_ModHandler; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GT_Utility; +import gregtech.api.util.MethodsReturnNonnullByDefault; + +/** + * Special Class for Furnace Recipe handling. + */ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class FurnaceBackend extends NonGTBackend { + + public FurnaceBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { + super(propertiesBuilder); + } + + @Override + protected GT_Recipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot, + @Nullable GT_Recipe cachedRecipe) { + if (items.length == 0 || items[0] == null) { + return null; + } + if (cachedRecipe != null && cachedRecipe.isRecipeInputEqual(false, true, fluids, items)) { + return cachedRecipe; + } + ItemStack output = GT_ModHandler.getSmeltingOutput(items[0], false, null); + return output == null ? null + : GT_Values.RA.stdBuilder() + .itemInputs(GT_Utility.copyAmount(1, items[0])) + .itemOutputs(output) + .duration(128) + .eut(4) + .noOptimize() + .build() + .orElse(null); + } + + @Override + public boolean containsInput(ItemStack item) { + return GT_ModHandler.getSmeltingOutput(item, false, null) != null; + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/LargeBoilerFuelBackend.java b/src/main/java/gregtech/api/recipe/maps/LargeBoilerFuelBackend.java new file mode 100644 index 0000000000..53152312f4 --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/LargeBoilerFuelBackend.java @@ -0,0 +1,132 @@ +package gregtech.api.recipe.maps; + +import java.util.Arrays; +import java.util.List; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +import gregtech.api.GregTech_API; +import gregtech.api.enums.ConfigCategories; +import gregtech.api.enums.GT_Values; +import gregtech.api.recipe.RecipeMapBackend; +import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; +import gregtech.api.util.GT_ModHandler; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.MethodsReturnNonnullByDefault; + +@SuppressWarnings({ "unused", "UnusedReturnValue" }) +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class LargeBoilerFuelBackend extends RecipeMapBackend { + + private static boolean addedGeneralDesc = false; + + private static final List<String> ALLOWED_SOLID_FUELS = Arrays.asList( + GregTech_API.sMachineFile.mConfig.getStringList( + "LargeBoiler.allowedFuels", + ConfigCategories.machineconfig.toString(), + new String[] { "gregtech:gt.blockreinforced:6", "gregtech:gt.blockreinforced:7" }, + "Allowed fuels for the Large Titanium Boiler and Large Tungstensteel Boiler")); + + public LargeBoilerFuelBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { + super(propertiesBuilder); + } + + public static boolean isAllowedSolidFuel(ItemStack stack) { + return isAllowedSolidFuel(Item.itemRegistry.getNameForObject(stack.getItem()), stack.getItemDamage()); + } + + public static boolean isAllowedSolidFuel(String itemRegistryName, int meta) { + return ALLOWED_SOLID_FUELS.contains(itemRegistryName + ":" + meta); + } + + public static boolean addAllowedSolidFuel(ItemStack stack) { + return addAllowedSolidFuel(Item.itemRegistry.getNameForObject(stack.getItem()), stack.getItemDamage()); + } + + public static boolean addAllowedSolidFuel(String itemregistryName, int meta) { + return ALLOWED_SOLID_FUELS.add(itemregistryName + ":" + meta); + } + + public GT_Recipe addDenseLiquidRecipe(GT_Recipe recipe) { + return addRecipe(recipe, ((double) recipe.mSpecialValue) / 10, false); + } + + public GT_Recipe addDieselRecipe(GT_Recipe recipe) { + return addRecipe(recipe, ((double) recipe.mSpecialValue) / 40, false); + } + + public void addSolidRecipes(ItemStack... itemStacks) { + for (ItemStack itemStack : itemStacks) { + addSolidRecipe(itemStack); + } + } + + @Nullable + public GT_Recipe addSolidRecipe(@Nullable ItemStack fuelItemStack) { + if (fuelItemStack == null) { + return null; + } + if (!addedGeneralDesc) { + GT_Values.RA.stdBuilder() + .duration(1) + .eut(1) + .specialValue(1) + .setNEIDesc( + "Not all solid fuels are listed.", + "Any item that burns in a", + "vanilla furnace will burn in", + "a Large Bronze or Steel Boiler.") + .build() + .map(this::compileRecipe); + addedGeneralDesc = true; + } + + String registryName = Item.itemRegistry.getNameForObject(fuelItemStack.getItem()); + boolean isHighTierAllowed = ALLOWED_SOLID_FUELS.contains(registryName + ":" + fuelItemStack.getItemDamage()); + return GT_Values.RA.stdBuilder() + .itemInputs(fuelItemStack) + .duration(1) + .eut(0) + .specialValue(GT_ModHandler.getFuelValue(fuelItemStack) / 1600) + .build() + .map(r -> addRecipe(r, ((double) GT_ModHandler.getFuelValue(fuelItemStack)) / 1600, isHighTierAllowed)) + .orElse(null); + } + + private GT_Recipe addRecipe(GT_Recipe recipe, double baseBurnTime, boolean isHighTierAllowed) { + // Some recipes will have a burn time like 15.9999999 and % always rounds down + double floatErrorCorrection = 0.0001; + + double bronzeBurnTime = baseBurnTime * 2 + floatErrorCorrection; + bronzeBurnTime -= bronzeBurnTime % 0.05; + double steelBurnTime = baseBurnTime + floatErrorCorrection; + steelBurnTime -= steelBurnTime % 0.05; + double titaniumBurnTime = baseBurnTime * 0.3 + floatErrorCorrection; + titaniumBurnTime -= titaniumBurnTime % 0.05; + double tungstensteelBurnTime = baseBurnTime * 0.15 + floatErrorCorrection; + tungstensteelBurnTime -= tungstensteelBurnTime % 0.05; + + if (isHighTierAllowed) { + recipe.setNeiDesc( + "Burn time in seconds:", + String.format("Bronze Boiler: %.4f", bronzeBurnTime), + String.format("Steel Boiler: %.4f", steelBurnTime), + String.format("Titanium Boiler: %.4f", titaniumBurnTime), + String.format("Tungstensteel Boiler: %.4f", tungstensteelBurnTime)); + } else { + recipe.setNeiDesc( + "Burn time in seconds:", + String.format("Bronze Boiler: %.4f", bronzeBurnTime), + String.format("Steel Boiler: %.4f", steelBurnTime), + "Titanium Boiler: Not allowed", + "Tungstenst. Boiler: Not allowed"); + } + + return compileRecipe(recipe); + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/LargeBoilerFuelFrontend.java b/src/main/java/gregtech/api/recipe/maps/LargeBoilerFuelFrontend.java new file mode 100644 index 0000000000..dbe7f6fe2f --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/LargeBoilerFuelFrontend.java @@ -0,0 +1,25 @@ +package gregtech.api.recipe.maps; + +import javax.annotation.ParametersAreNonnullByDefault; + +import gregtech.api.recipe.BasicUIPropertiesBuilder; +import gregtech.api.recipe.NEIRecipePropertiesBuilder; +import gregtech.api.recipe.RecipeMapFrontend; +import gregtech.api.util.MethodsReturnNonnullByDefault; +import gregtech.nei.RecipeDisplayInfo; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class LargeBoilerFuelFrontend extends RecipeMapFrontend { + + public LargeBoilerFuelFrontend(BasicUIPropertiesBuilder uiPropertiesBuilder, + NEIRecipePropertiesBuilder neiPropertiesBuilder) { + super(uiPropertiesBuilder, neiPropertiesBuilder); + } + + @Override + protected void drawEnergyInfo(RecipeDisplayInfo recipeInfo) {} + + @Override + protected void drawDurationInfo(RecipeDisplayInfo recipeInfo) {} +} diff --git a/src/main/java/gregtech/api/recipe/maps/LargeNEIFrontend.java b/src/main/java/gregtech/api/recipe/maps/LargeNEIFrontend.java new file mode 100644 index 0000000000..70184a83de --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/LargeNEIFrontend.java @@ -0,0 +1,65 @@ +package gregtech.api.recipe.maps; + +import java.util.List; + +import javax.annotation.ParametersAreNonnullByDefault; + +import com.gtnewhorizons.modularui.api.math.Pos2d; +import com.gtnewhorizons.modularui.api.math.Size; + +import gregtech.api.recipe.BasicUIPropertiesBuilder; +import gregtech.api.recipe.NEIRecipePropertiesBuilder; +import gregtech.api.recipe.RecipeMapFrontend; +import gregtech.api.util.MethodsReturnNonnullByDefault; +import gregtech.common.gui.modularui.UIHelper; + +/** + * Nicely display NEI with many items and fluids. Remember to call + * If row count >= 6, it doesn't fit in 2 recipes per page, so change it via IMC. + */ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class LargeNEIFrontend extends RecipeMapFrontend { + + private static final int xDirMaxCount = 3; + private static final int yOrigin = 8; + + private final int itemRowCount; + private final int fluidRowCount; + + public LargeNEIFrontend(BasicUIPropertiesBuilder uiPropertiesBuilder, + NEIRecipePropertiesBuilder neiPropertiesBuilder) { + super(uiPropertiesBuilder.logoPos(new Pos2d(80, 62)), neiPropertiesBuilder); + this.itemRowCount = getItemRowCount(); + this.fluidRowCount = getFluidRowCount(); + neiProperties.recipeBackgroundSize = new Size(170, 82 + (Math.max(itemRowCount + fluidRowCount - 4, 0)) * 18); + } + + @Override + public List<Pos2d> getItemInputPositions(int itemInputCount) { + return UIHelper.getGridPositions(itemInputCount, 16, yOrigin, xDirMaxCount); + } + + @Override + public List<Pos2d> getItemOutputPositions(int itemOutputCount) { + return UIHelper.getGridPositions(itemOutputCount, 106, yOrigin, xDirMaxCount); + } + + @Override + public List<Pos2d> getFluidInputPositions(int fluidInputCount) { + return UIHelper.getGridPositions(fluidInputCount, 16, yOrigin + itemRowCount * 18, xDirMaxCount); + } + + @Override + public List<Pos2d> getFluidOutputPositions(int fluidOutputCount) { + return UIHelper.getGridPositions(fluidOutputCount, 106, yOrigin + itemRowCount * 18, xDirMaxCount); + } + + private int getItemRowCount() { + return (Math.max(uiProperties.maxItemInputs, uiProperties.maxItemOutputs) - 1) / xDirMaxCount + 1; + } + + private int getFluidRowCount() { + return (Math.max(uiProperties.maxFluidInputs, uiProperties.maxFluidOutputs) - 1) / xDirMaxCount + 1; + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/MicrowaveBackend.java b/src/main/java/gregtech/api/recipe/maps/MicrowaveBackend.java new file mode 100644 index 0000000000..53623cb0c7 --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/MicrowaveBackend.java @@ -0,0 +1,145 @@ +package gregtech.api.recipe.maps; + +import static gregtech.api.enums.GT_Values.W; +import static gregtech.api.util.GT_RecipeConstants.EXPLODE; +import static gregtech.api.util.GT_RecipeConstants.ON_FIRE; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntityFurnace; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.api.enums.GT_Values; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.SubTag; +import gregtech.api.objects.ItemData; +import gregtech.api.objects.MaterialStack; +import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; +import gregtech.api.util.GT_Log; +import gregtech.api.util.GT_ModHandler; +import gregtech.api.util.GT_OreDictUnificator; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GT_RecipeBuilder; +import gregtech.api.util.GT_Utility; +import gregtech.api.util.MethodsReturnNonnullByDefault; + +/** + * Special Class for Microwave Recipe handling. + */ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class MicrowaveBackend extends NonGTBackend { + + public MicrowaveBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { + super(propertiesBuilder); + } + + @Override + protected GT_Recipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot, + @Nullable GT_Recipe cachedRecipe) { + if (items.length == 0 || items[0] == null) { + return null; + } + if (cachedRecipe != null && cachedRecipe.isRecipeInputEqual(false, true, fluids, items)) { + return cachedRecipe; + } + + ItemStack output = GT_ModHandler.getSmeltingOutput(items[0], false, null); + + if (GT_Utility.areStacksEqual(items[0], new ItemStack(Items.book, 1, W))) { + return GT_Values.RA.stdBuilder() + .itemInputs(GT_Utility.copyAmount(1, items[0])) + .itemOutputs(GT_Utility.getWrittenBook("Manual_Microwave", ItemList.Book_Written_03.get(1))) + .duration(32) + .eut(4) + .noOptimize() + .build() + .orElse(null); + } + + // Check Container Item of Input since it is around the Input, then the Input itself, then Container Item of + // Output and last check the Output itself + for (ItemStack item : new ItemStack[] { GT_Utility.getContainerItem(items[0], true), items[0], + GT_Utility.getContainerItem(output, true), output }) { + if (item == null) continue; + if (GT_Utility.areStacksEqual(item, new ItemStack(Blocks.netherrack, 1, W), true) + || GT_Utility.areStacksEqual(item, new ItemStack(Blocks.tnt, 1, W), true) + || GT_Utility.areStacksEqual(item, new ItemStack(Items.egg, 1, W), true) + || GT_Utility.areStacksEqual(item, new ItemStack(Items.firework_charge, 1, W), true) + || GT_Utility.areStacksEqual(item, new ItemStack(Items.fireworks, 1, W), true) + || GT_Utility.areStacksEqual(item, new ItemStack(Items.fire_charge, 1, W), true)) { + GT_Log.exp + .println("Microwave Explosion due to TNT || EGG || FIREWORKCHARGE || FIREWORK || FIRE CHARGE"); + return GT_RecipeBuilder.empty() + .metadata(EXPLODE, true) + .build() + .orElse(null); + } + + ItemData itemData = GT_OreDictUnificator.getItemData(item); + if (itemData != null) { + if (itemData.mMaterial != null && itemData.mMaterial.mMaterial != null) { + if (itemData.mMaterial.mMaterial.contains(SubTag.METAL) + || itemData.mMaterial.mMaterial.contains(SubTag.EXPLOSIVE)) { + GT_Log.exp.println("Microwave Explosion due to METAL insertion"); + return GT_RecipeBuilder.empty() + .metadata(EXPLODE, true) + .build() + .orElse(null); + } + if (itemData.mMaterial.mMaterial.contains(SubTag.FLAMMABLE)) { + GT_Log.exp.println("Microwave INFLAMMATION due to FLAMMABLE insertion"); + return GT_RecipeBuilder.empty() + .metadata(ON_FIRE, true) + .build() + .orElse(null); + } + } + for (MaterialStack materialStack : itemData.mByProducts) { + if (materialStack == null) continue; + if (materialStack.mMaterial.contains(SubTag.METAL) + || materialStack.mMaterial.contains(SubTag.EXPLOSIVE)) { + GT_Log.exp.println("Microwave Explosion due to METAL insertion"); + return GT_RecipeBuilder.empty() + .metadata(EXPLODE, true) + .build() + .orElse(null); + } + if (materialStack.mMaterial.contains(SubTag.FLAMMABLE)) { + GT_Log.exp.println("Microwave INFLAMMATION due to FLAMMABLE insertion"); + return GT_RecipeBuilder.empty() + .metadata(ON_FIRE, true) + .build() + .orElse(null); + } + } + } + if (TileEntityFurnace.getItemBurnTime(item) > 0) { + GT_Log.exp.println("Microwave INFLAMMATION due to BURNABLE insertion"); + return GT_RecipeBuilder.empty() + .metadata(ON_FIRE, true) + .build() + .orElse(null); + } + } + + return output == null ? null + : GT_Values.RA.stdBuilder() + .itemInputs(GT_Utility.copyAmount(1, items[0])) + .itemOutputs(output) + .duration(32) + .eut(4) + .noOptimize() + .build() + .orElse(null); + } + + @Override + public boolean containsInput(ItemStack item) { + return GT_ModHandler.getSmeltingOutput(item, false, null) != null; + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/NonGTBackend.java b/src/main/java/gregtech/api/recipe/maps/NonGTBackend.java new file mode 100644 index 0000000000..1e871df372 --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/NonGTBackend.java @@ -0,0 +1,52 @@ +package gregtech.api.recipe.maps; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.api.recipe.RecipeMapBackend; +import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.MethodsReturnNonnullByDefault; + +/** + * Abstract class for general recipe handling of non GT recipes + */ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public abstract class NonGTBackend extends RecipeMapBackend { + + public NonGTBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { + super(propertiesBuilder); + } + + @Override + protected abstract GT_Recipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, + @Nullable ItemStack specialSlot, @Nullable GT_Recipe cachedRecipe); + + @Override + protected boolean doesOverwriteFindRecipe() { + return true; + } + + @Override + public boolean containsInput(ItemStack item) { + return false; + } + + @Override + public boolean containsInput(Fluid fluid) { + return false; + } + + @Override + public void reInit() {} + + @Override + protected GT_Recipe addToItemMap(GT_Recipe recipe) { + return recipe; + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/OilCrackerBackend.java b/src/main/java/gregtech/api/recipe/maps/OilCrackerBackend.java new file mode 100644 index 0000000000..c2c312a48a --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/OilCrackerBackend.java @@ -0,0 +1,41 @@ +package gregtech.api.recipe.maps; + +import java.util.HashSet; +import java.util.Set; + +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraftforge.fluids.FluidStack; + +import gregtech.api.recipe.RecipeMapBackend; +import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.MethodsReturnNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class OilCrackerBackend extends RecipeMapBackend { + + private final Set<String> validCatalystFluidNames = new HashSet<>(); + + public OilCrackerBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { + super(propertiesBuilder); + } + + @Override + public GT_Recipe compileRecipe(GT_Recipe recipe) { + super.compileRecipe(recipe); + if (recipe.mFluidInputs != null && recipe.mFluidInputs.length > 1 && recipe.mFluidInputs[1] != null) { + validCatalystFluidNames.add( + recipe.mFluidInputs[1].getFluid() + .getName()); + } + return recipe; + } + + public boolean isValidCatalystFluid(FluidStack fluid) { + return validCatalystFluidNames.contains( + fluid.getFluid() + .getName()); + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/PrinterBackend.java b/src/main/java/gregtech/api/recipe/maps/PrinterBackend.java new file mode 100644 index 0000000000..a933886447 --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/PrinterBackend.java @@ -0,0 +1,142 @@ +package gregtech.api.recipe.maps; + +import static gregtech.api.enums.GT_Values.L; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.api.enums.Dyes; +import gregtech.api.enums.GT_Values; +import gregtech.api.enums.ItemList; +import gregtech.api.recipe.RecipeMapBackend; +import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; +import gregtech.api.util.GT_ModHandler; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GT_Utility; +import gregtech.api.util.MethodsReturnNonnullByDefault; + +/** + * Special Class for Printer handling. + */ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class PrinterBackend extends RecipeMapBackend { + + public PrinterBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { + super(propertiesBuilder); + } + + @Override + protected GT_Recipe modifyFoundRecipe(GT_Recipe recipe, ItemStack[] items, FluidStack[] fluids, + @Nullable ItemStack specialSlot) { + if (items[0].getItem() == Items.paper) { + assert specialSlot != null; + if (!ItemList.Tool_DataStick.isStackEqual(specialSlot, false, true)) return null; + NBTTagCompound nbt = specialSlot.getTagCompound(); + if (nbt == null || GT_Utility.isStringInvalid(nbt.getString("title")) + || GT_Utility.isStringInvalid(nbt.getString("author"))) return null; + + recipe = recipe.copy(); + recipe.mCanBeBuffered = false; + recipe.mOutputs[0].setTagCompound(nbt); + return recipe; + } + if (items[0].getItem() == Items.map) { + assert specialSlot != null; + if (!ItemList.Tool_DataStick.isStackEqual(specialSlot, false, true)) return null; + NBTTagCompound nbt = specialSlot.getTagCompound(); + if (nbt == null || !nbt.hasKey("map_id")) return null; + + recipe = recipe.copy(); + recipe.mCanBeBuffered = false; + recipe.mOutputs[0].setItemDamage(nbt.getShort("map_id")); + return recipe; + } + if (ItemList.Paper_Punch_Card_Empty.isStackEqual(items[0], false, true)) { + assert specialSlot != null; + if (!ItemList.Tool_DataStick.isStackEqual(specialSlot, false, true)) return null; + NBTTagCompound nbt = specialSlot.getTagCompound(); + if (nbt == null || !nbt.hasKey("GT.PunchCardData")) return null; + + recipe = recipe.copy(); + recipe.mCanBeBuffered = false; + recipe.mOutputs[0].setTagCompound( + GT_Utility.getNBTContainingString( + new NBTTagCompound(), + "GT.PunchCardData", + nbt.getString("GT.PunchCardData"))); + return recipe; + } + return recipe; + } + + @Override + protected GT_Recipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { + if (items.length == 0 || items[0] == null || fluids.length == 0 || fluids[0] == null) { + return null; + } + Dyes dye = null; + for (Dyes tDye : Dyes.VALUES) if (tDye.isFluidDye(fluids[0])) { + dye = tDye; + break; + } + if (dye == null) return null; + + ItemStack batchRecolorOutput = GT_ModHandler.getAllRecipeOutput( + null, + items[0], + items[0], + items[0], + items[0], + ItemList.DYE_ONLY_ITEMS[dye.mIndex].get(1), + items[0], + items[0], + items[0], + items[0]); + if (batchRecolorOutput != null) { + return GT_Values.RA.stdBuilder() + .itemInputs(GT_Utility.copyAmount(8, items[0])) + .itemOutputs(batchRecolorOutput) + .fluidInputs(new FluidStack(fluids[0].getFluid(), (int) L)) + .duration(256) + .eut(2) + .hidden() + .build() + .map(this::compileRecipe) + .orElse(null); + } + + ItemStack singleRecolorOutput = GT_ModHandler + .getAllRecipeOutput(null, items[0], ItemList.DYE_ONLY_ITEMS[dye.mIndex].get(1)); + if (singleRecolorOutput != null) { + return GT_Values.RA.stdBuilder() + .itemInputs(GT_Utility.copyAmount(1, items[0])) + .itemOutputs(singleRecolorOutput) + .fluidInputs(new FluidStack(fluids[0].getFluid(), (int) L)) + .duration(32) + .eut(2) + .hidden() + .build() + .map(this::compileRecipe) + .orElse(null); + } + + return null; + } + + @Override + public boolean containsInput(ItemStack item) { + return true; + } + + @Override + public boolean containsInput(Fluid fluid) { + return super.containsInput(fluid) || Dyes.isAnyFluidDye(fluid); + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/RecyclerBackend.java b/src/main/java/gregtech/api/recipe/maps/RecyclerBackend.java new file mode 100644 index 0000000000..5d65468004 --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/RecyclerBackend.java @@ -0,0 +1,51 @@ +package gregtech.api.recipe.maps; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.api.enums.GT_Values; +import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; +import gregtech.api.util.GT_ModHandler; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GT_Utility; +import gregtech.api.util.MethodsReturnNonnullByDefault; + +/** + * Special Class for Recycler Recipe handling. + */ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class RecyclerBackend extends NonGTBackend { + + public RecyclerBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { + super(propertiesBuilder); + } + + @Override + protected GT_Recipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot, + @Nullable GT_Recipe cachedRecipe) { + if (items.length == 0 || items[0] == null) { + return null; + } + if (cachedRecipe != null && cachedRecipe.isRecipeInputEqual(false, true, fluids, items)) { + return cachedRecipe; + } + return GT_Values.RA.stdBuilder() + .itemInputs(GT_Utility.copyAmount(1, items[0])) + .itemOutputs(GT_ModHandler.getRecyclerOutput(items[0], 0)) + .outputChances(1250) + .duration(45) + .eut(1) + .noOptimize() + .build() + .orElse(null); + } + + @Override + public boolean containsInput(ItemStack item) { + return GT_ModHandler.getRecyclerOutput(item, 0) != null; + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/ReplicatorBackend.java b/src/main/java/gregtech/api/recipe/maps/ReplicatorBackend.java new file mode 100644 index 0000000000..f201698457 --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/ReplicatorBackend.java @@ -0,0 +1,100 @@ +package gregtech.api.recipe.maps; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.GT_Mod; +import gregtech.api.enums.Element; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.enums.TierEU; +import gregtech.api.recipe.RecipeMapBackend; +import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GT_RecipeBuilder; +import gregtech.api.util.GT_RecipeConstants; +import gregtech.api.util.GT_Utility; +import gregtech.api.util.MethodsReturnNonnullByDefault; +import gregtech.common.items.behaviors.Behaviour_DataOrb; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class ReplicatorBackend extends RecipeMapBackend { + + private final Map<Materials, GT_Recipe> recipesByMaterial = new HashMap<>(); + + public ReplicatorBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { + super(propertiesBuilder.recipeEmitter(ReplicatorBackend::replicatorRecipeEmitter)); + } + + @Override + public GT_Recipe compileRecipe(GT_Recipe recipe) { + super.compileRecipe(recipe); + Materials material = recipe.getMetadata(GT_RecipeConstants.MATERIAL); + assert material != null; // checked by replicatorRecipeEmitter + recipesByMaterial.put(material, recipe); + return recipe; + } + + @Override + protected boolean doesOverwriteFindRecipe() { + return true; + } + + @Override + protected GT_Recipe overwriteFindRecipe(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot, + @Nullable GT_Recipe cachedRecipe) { + if (specialSlot == null) { + return null; + } + Materials foundMaterial = getMaterialFromDataOrb(specialSlot); + if (foundMaterial == null) { + return null; + } + return recipesByMaterial.getOrDefault(foundMaterial, null); + } + + @Nullable + private static Materials getMaterialFromDataOrb(ItemStack stack) { + if (ItemList.Tool_DataOrb.isStackEqual(stack, false, true) && Behaviour_DataOrb.getDataTitle(stack) + .equals("Elemental-Scan")) { + return Element.get(Behaviour_DataOrb.getDataName(stack)).mLinkedMaterials.stream() + .findFirst() + .orElse(null); + } + return null; + } + + private static Collection<GT_Recipe> replicatorRecipeEmitter(GT_RecipeBuilder builder) { + Materials material = builder.getMetadata(GT_RecipeConstants.MATERIAL); + if (material == null) { + throw new IllegalStateException("GT_RecipeConstants.MATERIAL must be set for replicator recipe"); + } + return Optional.of(material) + .map(material1 -> material1.mElement) + .map(Element::getMass) + .map(ReplicatorBackend::getUUMAmountFromMass) + .flatMap( + uum -> builder.fluidInputs(Materials.UUMatter.getFluid(uum)) + .duration(GT_Utility.safeInt(uum * 512L, 1)) + .eut(TierEU.RECIPE_LV) + .ignoreCollision() + .noOptimize() + .build()) + .map(Collections::singletonList) + .orElse(Collections.emptyList()); + } + + private static int getUUMAmountFromMass(long mass) { + return GT_Utility.safeInt((long) Math.pow(mass, GT_Mod.gregtechproxy.replicatorExponent), 1); + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/SpaceProjectFrontend.java b/src/main/java/gregtech/api/recipe/maps/SpaceProjectFrontend.java new file mode 100644 index 0000000000..98463dcc4d --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/SpaceProjectFrontend.java @@ -0,0 +1,131 @@ +package gregtech.api.recipe.maps; + +import static gregtech.api.util.GT_Utility.formatNumbers; +import static net.minecraft.util.EnumChatFormatting.GRAY; +import static net.minecraft.util.StatCollector.translateToLocal; + +import java.util.List; +import java.util.function.Supplier; + +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.util.EnumChatFormatting; + +import com.gtnewhorizons.modularui.api.drawable.IDrawable; +import com.gtnewhorizons.modularui.api.forge.IItemHandlerModifiable; +import com.gtnewhorizons.modularui.api.math.Alignment; +import com.gtnewhorizons.modularui.api.math.Pos2d; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.common.widget.DrawableWidget; +import com.gtnewhorizons.modularui.common.widget.ProgressBar; + +import appeng.util.ReadableNumberConverter; +import codechicken.lib.gui.GuiDraw; +import codechicken.nei.PositionedStack; +import gregtech.api.gui.modularui.GT_UITextures; +import gregtech.api.recipe.BasicUIPropertiesBuilder; +import gregtech.api.recipe.NEIRecipePropertiesBuilder; +import gregtech.api.recipe.RecipeMapFrontend; +import gregtech.api.util.MethodsReturnNonnullByDefault; +import gregtech.common.gui.modularui.UIHelper; +import gregtech.common.misc.spaceprojects.SpaceProjectManager; +import gregtech.common.misc.spaceprojects.SpaceProjectManager.FakeSpaceProjectRecipe; +import gregtech.common.misc.spaceprojects.interfaces.ISpaceProject; +import gregtech.nei.GT_NEI_DefaultHandler; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class SpaceProjectFrontend extends RecipeMapFrontend { + + IDrawable projectTexture; + + public SpaceProjectFrontend(BasicUIPropertiesBuilder uiPropertiesBuilder, + NEIRecipePropertiesBuilder neiPropertiesBuilder) { + super(uiPropertiesBuilder, neiPropertiesBuilder); + } + + @Override + public ModularWindow.Builder createNEITemplate(IItemHandlerModifiable itemInputsInventory, + IItemHandlerModifiable itemOutputsInventory, IItemHandlerModifiable specialSlotInventory, + IItemHandlerModifiable fluidInputsInventory, IItemHandlerModifiable fluidOutputsInventory, + Supplier<Float> progressSupplier, Pos2d windowOffset) { + ModularWindow.Builder builder = super.createNEITemplate( + itemInputsInventory, + itemOutputsInventory, + specialSlotInventory, + fluidInputsInventory, + fluidOutputsInventory, + progressSupplier, + windowOffset); + builder.widget( + new DrawableWidget().setDrawable(() -> projectTexture) + .setSize(18, 18) + .setPos(new Pos2d(124, 28).add(windowOffset))); + return builder; + } + + @Override + public List<Pos2d> getItemInputPositions(int itemInputCount) { + return UIHelper.getGridPositions(itemInputCount, 16, 28, 3); + } + + @Override + public List<Pos2d> getFluidInputPositions(int fluidInputCount) { + return UIHelper.getGridPositions(fluidInputCount, 88, 28, 1); + } + + @Override + protected List<String> handleNEIItemInputTooltip(List<String> currentTip, + GT_NEI_DefaultHandler.FixedPositionedStack pStack) { + super.handleNEIItemOutputTooltip(currentTip, pStack); + if (pStack.isFluid()) return currentTip; + currentTip.add(GRAY + translateToLocal("Item Count: ") + formatNumbers(pStack.realStackSize)); + return currentTip; + } + + @Override + public void drawNEIOverlays(GT_NEI_DefaultHandler.CachedDefaultRecipe neiCachedRecipe) { + for (PositionedStack stack : neiCachedRecipe.mInputs) { + if (stack instanceof GT_NEI_DefaultHandler.FixedPositionedStack pStack && stack.item != null + && !pStack.isFluid()) { + int stackSize = ((GT_NEI_DefaultHandler.FixedPositionedStack) stack).realStackSize; + String displayString; + if (stack.item.stackSize > 9999) { + displayString = ReadableNumberConverter.INSTANCE.toWideReadableForm(stackSize); + } else { + displayString = String.valueOf(stackSize); + } + drawNEIOverlayText(displayString, stack, 0xffffff, 0.5f, true, Alignment.BottomRight); + } + } + if (neiCachedRecipe.mRecipe instanceof FakeSpaceProjectRecipe) { + ISpaceProject project = SpaceProjectManager + .getProject(((FakeSpaceProjectRecipe) neiCachedRecipe.mRecipe).projectName); + if (project != null) { + projectTexture = project.getTexture(); + GuiDraw.drawStringC(EnumChatFormatting.BOLD + project.getLocalizedName(), 85, 0, 0x404040, false); + } + } + } + + @Override + public void addProgressBar(ModularWindow.Builder builder, Supplier<Float> progressSupplier, Pos2d windowOffset) { + int bar1Width = 17; + int bar2Width = 18; + List<Supplier<Float>> splitProgress = splitProgress(progressSupplier, bar1Width, bar2Width); + builder.widget( + new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_1, 17) + .setDirection(ProgressBar.Direction.RIGHT) + .setProgress(splitProgress.get(0)) + .setSynced(false, false) + .setPos(new Pos2d(70, 28).add(windowOffset)) + .setSize(bar1Width, 72)); + builder.widget( + new ProgressBar().setTexture(GT_UITextures.PROGRESSBAR_ASSEMBLY_LINE_2, 18) + .setDirection(ProgressBar.Direction.RIGHT) + .setProgress(splitProgress.get(1)) + .setSynced(false, false) + .setPos(new Pos2d(106, 28).add(windowOffset)) + .setSize(bar2Width, 72)); + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/TranscendentPlasmaMixerFrontend.java b/src/main/java/gregtech/api/recipe/maps/TranscendentPlasmaMixerFrontend.java new file mode 100644 index 0000000000..7a5d7ff164 --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/TranscendentPlasmaMixerFrontend.java @@ -0,0 +1,56 @@ +package gregtech.api.recipe.maps; + +import static gregtech.api.util.GT_Utility.formatNumbers; + +import java.util.List; + +import javax.annotation.ParametersAreNonnullByDefault; + +import com.gtnewhorizons.modularui.api.math.Pos2d; + +import gregtech.api.recipe.BasicUIPropertiesBuilder; +import gregtech.api.recipe.NEIRecipePropertiesBuilder; +import gregtech.api.recipe.RecipeMapFrontend; +import gregtech.api.util.GT_Utility; +import gregtech.api.util.MethodsReturnNonnullByDefault; +import gregtech.common.gui.modularui.UIHelper; +import gregtech.nei.RecipeDisplayInfo; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class TranscendentPlasmaMixerFrontend extends RecipeMapFrontend { + + public TranscendentPlasmaMixerFrontend(BasicUIPropertiesBuilder uiPropertiesBuilder, + NEIRecipePropertiesBuilder neiPropertiesBuilder) { + super(uiPropertiesBuilder, neiPropertiesBuilder); + } + + @Override + public List<Pos2d> getItemInputPositions(int itemInputCount) { + return UIHelper.getGridPositions(itemInputCount, 60, 8, 1); + } + + @Override + public List<Pos2d> getFluidInputPositions(int fluidInputCount) { + return UIHelper.getGridPositions(fluidInputCount, 6, 26, 4, 5); + } + + @Override + public List<Pos2d> getFluidOutputPositions(int fluidOutputCount) { + return UIHelper.getGridPositions(fluidOutputCount, 114, 44, 1); + } + + @Override + protected void drawEnergyInfo(RecipeDisplayInfo recipeInfo) { + // These look odd because recipeInfo.recipe.mEUt is actually the EU per litre of fluid processed, not + // the EU/t. + recipeInfo.drawText( + GT_Utility.trans("152", "Total: ") + + formatNumbers(1000L * recipeInfo.recipe.mDuration / 100L * recipeInfo.recipe.mEUt) + + " EU"); + // 1000 / (20 ticks * 5 seconds) = 10L/t. 10L/t * x EU/L = 10 * x EU/t. + long averageUsage = 10L * recipeInfo.recipe.mEUt; + recipeInfo.drawText( + "Average: " + formatNumbers(averageUsage) + " EU/t" + GT_Utility.getTierNameWithParentheses(averageUsage)); + } +} diff --git a/src/main/java/gregtech/api/recipe/maps/UnpackagerBackend.java b/src/main/java/gregtech/api/recipe/maps/UnpackagerBackend.java new file mode 100644 index 0000000000..e7297f0609 --- /dev/null +++ b/src/main/java/gregtech/api/recipe/maps/UnpackagerBackend.java @@ -0,0 +1,53 @@ +package gregtech.api.recipe.maps; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import gregtech.api.enums.GT_Values; +import gregtech.api.enums.ItemList; +import gregtech.api.recipe.RecipeMapBackend; +import gregtech.api.recipe.RecipeMapBackendPropertiesBuilder; +import gregtech.api.util.GT_ModHandler; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.MethodsReturnNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class UnpackagerBackend extends RecipeMapBackend { + + public UnpackagerBackend(RecipeMapBackendPropertiesBuilder propertiesBuilder) { + super(propertiesBuilder); + } + + @Override + protected GT_Recipe findFallback(ItemStack[] items, FluidStack[] fluids, @Nullable ItemStack specialSlot) { + if (items.length == 0 || !ItemList.IC2_Scrapbox.isStackEqual(items[0], false, true)) { + return null; + } + + ItemStack output = GT_ModHandler.getRandomScrapboxDrop(); + if (output == null) { + return null; + } + return GT_Values.RA.stdBuilder() + .itemInputs(ItemList.IC2_Scrapbox.get(1)) + .itemOutputs(output) + .duration(16) + .eut(1) + // It is not allowed to be buffered due to the random Output + .noBuffer() + // Due to its randomness it is not good if there are Items in the Output Slot, because those Items could + // manipulate the outcome. + .needsEmptyOutput() + .build() + .orElse(null); + } + + @Override + public boolean containsInput(ItemStack item) { + return ItemList.IC2_Scrapbox.isStackEqual(item, false, true) || super.containsInput(item); + } +} |