From 4bf4c2a043f033e44b875dc3bbf56a32c0a1d666 Mon Sep 17 00:00:00 2001 From: mezz Date: Thu, 20 Aug 2015 00:44:20 -0700 Subject: [PATCH] Fix #798 Add NEIIntegration (thanks @Tonius for original work) --- api/forestry | 2 +- build.gradle | 13 + lang | 2 +- src/main/java/codechicken/nei/LICENSE.txt | 21 -- .../java/codechicken/nei/VisiblityData.java | 38 --- .../codechicken/nei/api/INEIGuiHandler.java | 49 ---- .../nei/api/TaggedInventoryArea.java | 48 ---- .../core/utils/ShapedRecipeCustom.java | 6 +- .../core/utils/ShapelessRecipeCustom.java | 14 +- .../factory/gadgets/MachineSqueezer.java | 76 ++---- .../factory/recipes/FabricatorRecipe.java | 15 + .../factory/recipes/ISqueezerRecipe.java | 29 ++ .../factory/recipes/SqueezerRecipe.java | 58 ++++ .../{ => craftguide}/CraftGuideBottler.java | 2 +- .../{ => craftguide}/CraftGuideCarpenter.java | 2 +- .../CraftGuideCentrifuge.java | 2 +- .../CraftGuideCustomRecipes.java | 2 +- .../CraftGuideFabricator.java | 2 +- .../{ => craftguide}/CraftGuideFermenter.java | 2 +- .../CraftGuideIntegration.java | 2 +- .../{ => craftguide}/CraftGuideSqueezer.java | 15 +- .../{ => craftguide}/CraftGuideStill.java | 2 +- .../recipes/nei/INBTMatchingCachedRecipe.java | 21 ++ .../recipes/nei/IRecipeHandlerBase.java | 18 ++ .../recipes/nei/NEIHandlerBottler.java | 153 +++++++++++ .../recipes/nei/NEIHandlerCarpenter.java | 191 +++++++++++++ .../recipes/nei/NEIHandlerCentrifuge.java | 158 +++++++++++ .../recipes/nei/NEIHandlerFabricator.java | 258 ++++++++++++++++++ .../recipes/nei/NEIHandlerFermenter.java | 205 ++++++++++++++ .../recipes/nei/NEIHandlerMoistener.java | 156 +++++++++++ .../recipes/nei/NEIHandlerShapedCustom.java | 122 +++++++++ .../nei/NEIHandlerShapelessCustom.java | 112 ++++++++ .../recipes/nei/NEIHandlerSqueezer.java | 170 ++++++++++++ .../factory/recipes/nei/NEIHandlerStill.java | 118 ++++++++ .../recipes/nei/NEIIntegrationConfig.java | 52 ++++ .../factory/recipes/nei/NEIUtils.java | 123 +++++++++ .../recipes/nei/PositionedFluidTank.java | 135 +++++++++ .../recipes/nei/PositionedStackAdv.java | 74 +++++ .../recipes/nei/RecipeHandlerBase.java | 236 ++++++++++++++++ .../forestry/plugins/PluginArboriculture.java | 20 +- .../java/forestry/plugins/PluginFactory.java | 2 +- 41 files changed, 2490 insertions(+), 236 deletions(-) delete mode 100644 src/main/java/codechicken/nei/LICENSE.txt delete mode 100644 src/main/java/codechicken/nei/VisiblityData.java delete mode 100644 src/main/java/codechicken/nei/api/INEIGuiHandler.java delete mode 100644 src/main/java/codechicken/nei/api/TaggedInventoryArea.java create mode 100644 src/main/java/forestry/factory/recipes/ISqueezerRecipe.java create mode 100644 src/main/java/forestry/factory/recipes/SqueezerRecipe.java rename src/main/java/forestry/factory/recipes/{ => craftguide}/CraftGuideBottler.java (97%) mode change 100755 => 100644 rename src/main/java/forestry/factory/recipes/{ => craftguide}/CraftGuideCarpenter.java (98%) mode change 100755 => 100644 rename src/main/java/forestry/factory/recipes/{ => craftguide}/CraftGuideCentrifuge.java (98%) mode change 100755 => 100644 rename src/main/java/forestry/factory/recipes/{ => craftguide}/CraftGuideCustomRecipes.java (97%) mode change 100755 => 100644 rename src/main/java/forestry/factory/recipes/{ => craftguide}/CraftGuideFabricator.java (98%) mode change 100755 => 100644 rename src/main/java/forestry/factory/recipes/{ => craftguide}/CraftGuideFermenter.java (98%) mode change 100755 => 100644 rename src/main/java/forestry/factory/recipes/{ => craftguide}/CraftGuideIntegration.java (97%) mode change 100755 => 100644 rename src/main/java/forestry/factory/recipes/{ => craftguide}/CraftGuideSqueezer.java (80%) mode change 100755 => 100644 rename src/main/java/forestry/factory/recipes/{ => craftguide}/CraftGuideStill.java (97%) mode change 100755 => 100644 create mode 100644 src/main/java/forestry/factory/recipes/nei/INBTMatchingCachedRecipe.java create mode 100644 src/main/java/forestry/factory/recipes/nei/IRecipeHandlerBase.java create mode 100644 src/main/java/forestry/factory/recipes/nei/NEIHandlerBottler.java create mode 100644 src/main/java/forestry/factory/recipes/nei/NEIHandlerCarpenter.java create mode 100644 src/main/java/forestry/factory/recipes/nei/NEIHandlerCentrifuge.java create mode 100644 src/main/java/forestry/factory/recipes/nei/NEIHandlerFabricator.java create mode 100644 src/main/java/forestry/factory/recipes/nei/NEIHandlerFermenter.java create mode 100644 src/main/java/forestry/factory/recipes/nei/NEIHandlerMoistener.java create mode 100644 src/main/java/forestry/factory/recipes/nei/NEIHandlerShapedCustom.java create mode 100644 src/main/java/forestry/factory/recipes/nei/NEIHandlerShapelessCustom.java create mode 100644 src/main/java/forestry/factory/recipes/nei/NEIHandlerSqueezer.java create mode 100644 src/main/java/forestry/factory/recipes/nei/NEIHandlerStill.java create mode 100644 src/main/java/forestry/factory/recipes/nei/NEIIntegrationConfig.java create mode 100644 src/main/java/forestry/factory/recipes/nei/NEIUtils.java create mode 100644 src/main/java/forestry/factory/recipes/nei/PositionedFluidTank.java create mode 100644 src/main/java/forestry/factory/recipes/nei/PositionedStackAdv.java create mode 100644 src/main/java/forestry/factory/recipes/nei/RecipeHandlerBase.java diff --git a/api/forestry b/api/forestry index f8509521b..21564e033 160000 --- a/api/forestry +++ b/api/forestry @@ -1 +1 @@ -Subproject commit f8509521b617454973c2b3a6dfd8917a58efdb8a +Subproject commit 21564e0339e598ba9f1b43447992fb674066553c diff --git a/build.gradle b/build.gradle index d4bfef238..eba2e67a0 100755 --- a/build.gradle +++ b/build.gradle @@ -65,6 +65,10 @@ repositories { name "BuildCraft" artifactPattern "http://www.mod-buildcraft.com/releases/BuildCraft/[revision]/[module]-[revision]-[classifier].[ext]" } + maven { + name = "chickenbones" + url = "http://chickenbones.net/maven/" + } } configurations { @@ -75,6 +79,15 @@ configurations { dependencies { api 'net.industrial-craft:industrialcraft-2:2.2.713-experimental:api' api name: "buildcraft", version: "6.4.10", classifier: "dev" + + // http://files.minecraftforge.net/CodeChickenLib/ + compile "codechicken:CodeChickenLib:1.7.10-1.1.3.140:dev" + + // http://chickenbones.net/maven + compile "codechicken:CodeChickenCore:1.7.10-1.0.7.47:dev" + compile "codechicken:NotEnoughItems:1.7.10-1.0.5.111:dev" + compile "codechicken:NotEnoughItems:1.7.10-1.0.5.111:src" + testCompile 'junit:junit:4.12' } diff --git a/lang b/lang index 4393c919e..9addc2a26 160000 --- a/lang +++ b/lang @@ -1 +1 @@ -Subproject commit 4393c919e335259b050863f4f65ef9beb73ee052 +Subproject commit 9addc2a26f693c493bf2e3b7a7ec5b78a44e1a2d diff --git a/src/main/java/codechicken/nei/LICENSE.txt b/src/main/java/codechicken/nei/LICENSE.txt deleted file mode 100644 index 186cfbbc0..000000000 --- a/src/main/java/codechicken/nei/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 ChickenBones - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/src/main/java/codechicken/nei/VisiblityData.java b/src/main/java/codechicken/nei/VisiblityData.java deleted file mode 100644 index f5753aa8e..000000000 --- a/src/main/java/codechicken/nei/VisiblityData.java +++ /dev/null @@ -1,38 +0,0 @@ -package codechicken.nei; - -public class VisiblityData -{ - public boolean showUtilityButtons = true; - public boolean showStateButtons = true; - /** - * Item panel and associated buttons - */ - public boolean showItemPanel = true; - /** - * Item and search section - */ - public boolean showItemSection = true; - /** - * Dropdown and Item search field - */ - public boolean showSearchSection = true; - /** - * All widgets except options button - */ - public boolean showWidgets = true; - /** - * The entire NEI interface, aka hidden - */ - public boolean showNEI = true; - public boolean enableDeleteMode = true; - - public void translateDependancies() - { - if(!showNEI) - showWidgets = false; - if(!showWidgets) - showItemSection = showUtilityButtons = showStateButtons = false; - if(!showItemSection) - showSearchSection = showItemPanel = false; - } -} diff --git a/src/main/java/codechicken/nei/api/INEIGuiHandler.java b/src/main/java/codechicken/nei/api/INEIGuiHandler.java deleted file mode 100644 index 9ca8fb6cb..000000000 --- a/src/main/java/codechicken/nei/api/INEIGuiHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -package codechicken.nei.api; - -import codechicken.nei.VisiblityData; -import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.item.ItemStack; - -import java.util.List; - -/** - * If this is implemented on a gui, it will be automatically registered - */ -public interface INEIGuiHandler -{ - public VisiblityData modifyVisiblity(GuiContainer gui, VisiblityData currentVisibility); - - /** - * NEI will give the specified item to the InventoryRange returned if the player's inventory is full. - * return null for no range - */ - public Iterable getItemSpawnSlots(GuiContainer gui, ItemStack item); - - /** - * @return A list of TaggedInventoryAreas that will be used with the savestates. - */ - public List getInventoryAreas(GuiContainer gui); - - /** - * Handles clicks while an itemstack has been dragged from the item panel. Use this to set configurable slots and the like. - * Changes made to the stackSize of the dragged stack will be kept - * @param gui The current gui instance - * @param mousex The x position of the mouse - * @param mousey The y position of the mouse - * @param draggedStack The stack being dragged from the item panel - * @param button The button presed - * @return True if the drag n drop was handled. False to resume processing through other routes. The held stack will be deleted if draggedStack.stackSize == 0 - */ - public boolean handleDragNDrop(GuiContainer gui, int mousex, int mousey, ItemStack draggedStack, int button); - - /** - * Used to prevent the item panel from drawing on top of other gui elements. - * This function will also be called with a 1x1 size rectangle on the mouse position for determining if the given coordinate should override item panel functions such as scrolling - * @param x The x coordinate of the rectangle bounding the slot - * @param y The y coordinate of the rectangle bounding the slot - * @param w The w coordinate of the rectangle bounding the slot - * @param h The h coordinate of the rectangle bounding the slot - * @return true if the item panel slot within the specified rectangle should not be rendered. - */ - public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h); -} diff --git a/src/main/java/codechicken/nei/api/TaggedInventoryArea.java b/src/main/java/codechicken/nei/api/TaggedInventoryArea.java deleted file mode 100644 index b50d2e239..000000000 --- a/src/main/java/codechicken/nei/api/TaggedInventoryArea.java +++ /dev/null @@ -1,48 +0,0 @@ -package codechicken.nei.api; - -import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.inventory.Container; -import net.minecraft.inventory.IInventory; -import net.minecraft.item.ItemStack; - -import java.util.HashSet; - -public class TaggedInventoryArea -{ - public HashSet slots = new HashSet(); - public String tagName; - /** - * Only for player inventories. - */ - private IInventory inventory; - /** - * Other inventories - */ - private Container container; - - public TaggedInventoryArea(InventoryPlayer invPlayer) - { - this("InventoryPlayer", 0, 39, null); - inventory = invPlayer; - } - - public TaggedInventoryArea(String name, int first, int last, Container container) - { - this.container = container; - tagName = name; - for(int i = first; i <= last; i++) - slots.add(i); - } - - public ItemStack getStackInSlot(int i) - { - if(inventory != null) - return inventory.getStackInSlot(i); - return container.getSlot(i).getStack(); - } - - public boolean isContainer() - { - return inventory == null; - } -} diff --git a/src/main/java/forestry/core/utils/ShapedRecipeCustom.java b/src/main/java/forestry/core/utils/ShapedRecipeCustom.java index 5619f9e51..bac052769 100755 --- a/src/main/java/forestry/core/utils/ShapedRecipeCustom.java +++ b/src/main/java/forestry/core/utils/ShapedRecipeCustom.java @@ -51,6 +51,10 @@ public class ShapedRecipeCustom implements IDescriptiveRecipe { return this; } + public boolean preservesNbt() { + return preserveNBT; + } + @Override public int getWidth() { return width; @@ -63,7 +67,7 @@ public class ShapedRecipeCustom implements IDescriptiveRecipe { @Override public ItemStack getRecipeOutput() { - return product; + return product.copy(); } @Override diff --git a/src/main/java/forestry/core/utils/ShapelessRecipeCustom.java b/src/main/java/forestry/core/utils/ShapelessRecipeCustom.java index f515dd35c..db0355e83 100644 --- a/src/main/java/forestry/core/utils/ShapelessRecipeCustom.java +++ b/src/main/java/forestry/core/utils/ShapelessRecipeCustom.java @@ -31,7 +31,7 @@ public class ShapelessRecipeCustom implements IRecipe { private final List ingredients; private final ItemStack product; - private boolean preserveNBT = false; + private boolean preservesNbt = false; private ShapelessRecipeCustom(ItemStack product, ItemStack... ingredients) { this.ingredients = Arrays.asList(ingredients); @@ -39,10 +39,14 @@ public class ShapelessRecipeCustom implements IRecipe { } public ShapelessRecipeCustom setPreserveNBT() { - this.preserveNBT = true; + this.preservesNbt = true; return this; } + public boolean preservesNbt() { + return preservesNbt; + } + @Override public boolean matches(InventoryCrafting inventoryCrafting, World world) { ArrayList arraylist = new ArrayList(this.ingredients); @@ -76,7 +80,7 @@ public class ShapelessRecipeCustom implements IRecipe { public ItemStack getCraftingResult(InventoryCrafting inventoryCrafting) { ItemStack result = product.copy(); - if (preserveNBT) { + if (preservesNbt) { NBTTagCompound craftingNbt = RecipeUtil.getCraftingNbt(inventoryCrafting); if (craftingNbt == null) { return null; @@ -93,6 +97,10 @@ public class ShapelessRecipeCustom implements IRecipe { return ingredients.size(); } + public List getIngredients() { + return ingredients; + } + @Override public ItemStack getRecipeOutput() { return product.copy(); diff --git a/src/main/java/forestry/factory/gadgets/MachineSqueezer.java b/src/main/java/forestry/factory/gadgets/MachineSqueezer.java index 8e4429f12..6b6337ddb 100755 --- a/src/main/java/forestry/factory/gadgets/MachineSqueezer.java +++ b/src/main/java/forestry/factory/gadgets/MachineSqueezer.java @@ -15,7 +15,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; @@ -41,7 +43,6 @@ import forestry.core.config.Config; import forestry.core.config.Defaults; import forestry.core.fluids.FluidHelper; import forestry.core.fluids.TankManager; -import forestry.core.fluids.tanks.FilteredTank; import forestry.core.fluids.tanks.StandardTank; import forestry.core.gadgets.TilePowered; import forestry.core.interfaces.ILiquidTankContainer; @@ -55,6 +56,8 @@ import forestry.core.proxy.Proxies; import forestry.core.utils.EnumTankLevel; import forestry.core.utils.StackUtils; import forestry.core.utils.Utils; +import forestry.factory.recipes.ISqueezerRecipe; +import forestry.factory.recipes.SqueezerRecipe; public class MachineSqueezer extends TilePowered implements ISocketable, ISidedInventory, ILiquidTankContainer, ISpeedUpgradable { @@ -65,17 +68,17 @@ public class MachineSqueezer extends TilePowered implements ISocketable, ISidedI /* MEMBER */ private final TankManager tankManager; - private final FilteredTank productTank; + private final StandardTank productTank; private final SqueezerInventory inventory; - private Recipe currentRecipe; + private ISqueezerRecipe currentRecipe; public MachineSqueezer() { super(1100, 4000, 2000); this.inventory = new SqueezerInventory(this); setInternalInventory(this.inventory); setHints(Config.hints.get("squeezer")); - this.productTank = new FilteredTank(Defaults.PROCESSOR_TANK_CAPACITY, RecipeManager.recipeFluids); + this.productTank = new StandardTank(Defaults.PROCESSOR_TANK_CAPACITY); this.productTank.tankMode = StandardTank.TankMode.OUTPUT; this.tankManager = new TankManager(productTank); } @@ -145,15 +148,15 @@ public class MachineSqueezer extends TilePowered implements ISocketable, ISidedI @Override public boolean workCycle() { EntityPlayer player = Proxies.common.getPlayer(worldObj, getAccessHandler().getOwner()); - if (!inventory.removeResources(currentRecipe.resources, player)) { + if (!inventory.removeResources(currentRecipe.getResources(), player)) { return false; } - FluidStack resultFluid = currentRecipe.liquid; + FluidStack resultFluid = currentRecipe.getFluidOutput(); productTank.fill(resultFluid, true); - if (currentRecipe.remnants != null && worldObj.rand.nextInt(100) < currentRecipe.chance) { - ItemStack remnant = currentRecipe.remnants.copy(); + if (currentRecipe.getRemnants() != null && (worldObj.rand.nextFloat() < currentRecipe.getRemnantsChance())) { + ItemStack remnant = currentRecipe.getRemnants().copy(); inventory.addRemnant(remnant, true); } @@ -161,13 +164,16 @@ public class MachineSqueezer extends TilePowered implements ISocketable, ISidedI } private boolean checkRecipe() { - ItemStack[] resources = inventory.getResources(); - Recipe matchingRecipe = RecipeManager.findMatchingRecipe(resources); + ISqueezerRecipe matchingRecipe = null; + if (inventory.hasResources()) { + ItemStack[] resources = inventory.getResources(); + matchingRecipe = RecipeManager.findMatchingRecipe(resources); + } if (currentRecipe != matchingRecipe) { currentRecipe = matchingRecipe; if (currentRecipe != null) { - int recipeTime = currentRecipe.timePerItem; + int recipeTime = currentRecipe.getProcessingTime(); setTicksPerWorkCycle(recipeTime * TICKS_PER_RECIPE_TIME); setEnergyPerWorkCycle(recipeTime * ENERGY_PER_RECIPE_TIME); } @@ -189,11 +195,11 @@ public class MachineSqueezer extends TilePowered implements ISocketable, ISidedI if (hasResources) { hasRecipe = (currentRecipe != null); if (hasRecipe) { - FluidStack resultFluid = currentRecipe.liquid; + FluidStack resultFluid = currentRecipe.getFluidOutput(); canFill = (productTank.fill(resultFluid, false) == resultFluid.amount); - if (currentRecipe.remnants != null) { - canAdd = inventory.addRemnant(currentRecipe.remnants, false); + if (currentRecipe.getRemnants() != null) { + canAdd = inventory.addRemnant(currentRecipe.getRemnants(), false); } } } @@ -361,40 +367,14 @@ public class MachineSqueezer extends TilePowered implements ISocketable, ISidedI } } - /* RECIPE MANAGMENT */ - public static class Recipe { - - public final int timePerItem; - public final ItemStack[] resources; - public final FluidStack liquid; - public final ItemStack remnants; - public final int chance; - - public Recipe(int timePerItem, ItemStack[] resources, FluidStack liquid, ItemStack remnants, int chance) { - this.timePerItem = timePerItem; - this.resources = resources; - this.liquid = liquid; - this.remnants = remnants; - this.chance = chance; - } - - public boolean matches(ItemStack[] res) { - return StackUtils.containsSets(resources, res, true, false) > 0; - } - } - public static class RecipeManager implements ISqueezerManager { - public static final ArrayList recipes = new ArrayList(); - public static final HashSet recipeFluids = new HashSet(); - public static final HashSet recipeInputs = new HashSet(); + public static final List recipes = new ArrayList(); + public static final Set recipeInputs = new HashSet(); @Override public void addRecipe(int timePerItem, ItemStack[] resources, FluidStack liquid, ItemStack remnants, int chance) { - recipes.add(new MachineSqueezer.Recipe(timePerItem, resources, liquid, remnants, chance)); - if (liquid != null) { - recipeFluids.add(liquid.getFluid()); - } + recipes.add(new SqueezerRecipe(timePerItem, resources, liquid, remnants, chance / 100.0f)); if (resources != null) { recipeInputs.addAll(Arrays.asList(resources)); } @@ -405,9 +385,9 @@ public class MachineSqueezer extends TilePowered implements ISocketable, ISidedI addRecipe(timePerItem, resources, liquid, null, 0); } - public static Recipe findMatchingRecipe(ItemStack[] items) { - for (Recipe recipe : recipes) { - if (recipe.matches(items)) { + public static ISqueezerRecipe findMatchingRecipe(ItemStack[] items) { + for (ISqueezerRecipe recipe : recipes) { + if (StackUtils.containsSets(recipe.getResources(), items, true, false) > 0) { return recipe; } } @@ -431,8 +411,8 @@ public class MachineSqueezer extends TilePowered implements ISocketable, ISidedI public Map getRecipes() { HashMap recipeList = new HashMap(); - for (Recipe recipe : recipes) { - recipeList.put(recipe.resources, new Object[]{recipe.remnants, recipe.liquid}); + for (ISqueezerRecipe recipe : recipes) { + recipeList.put(recipe.getResources(), new Object[]{recipe.getRemnants(), recipe.getFluidOutput()}); } return recipeList; diff --git a/src/main/java/forestry/factory/recipes/FabricatorRecipe.java b/src/main/java/forestry/factory/recipes/FabricatorRecipe.java index 642b1bd9e..ec1dd2d7c 100644 --- a/src/main/java/forestry/factory/recipes/FabricatorRecipe.java +++ b/src/main/java/forestry/factory/recipes/FabricatorRecipe.java @@ -51,6 +51,21 @@ public class FabricatorRecipe implements IFabricatorRecipe { return internal.getIngredients(); } + @Override + public int getWidth() { + return internal.getWidth(); + } + + @Override + public int getHeight() { + return internal.getHeight(); + } + + @Override + public boolean preservesNbt() { + return internal.preservesNbt(); + } + @Override @Nullable public ItemStack getPlan() { diff --git a/src/main/java/forestry/factory/recipes/ISqueezerRecipe.java b/src/main/java/forestry/factory/recipes/ISqueezerRecipe.java new file mode 100644 index 000000000..de79cd1bf --- /dev/null +++ b/src/main/java/forestry/factory/recipes/ISqueezerRecipe.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes; + +import net.minecraft.item.ItemStack; + +import net.minecraftforge.fluids.FluidStack; + +public interface ISqueezerRecipe { + + ItemStack[] getResources(); + + int getProcessingTime(); + + ItemStack getRemnants(); + + float getRemnantsChance(); + + FluidStack getFluidOutput(); + +} diff --git a/src/main/java/forestry/factory/recipes/SqueezerRecipe.java b/src/main/java/forestry/factory/recipes/SqueezerRecipe.java new file mode 100644 index 000000000..eb30b316d --- /dev/null +++ b/src/main/java/forestry/factory/recipes/SqueezerRecipe.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes; + +import net.minecraft.item.ItemStack; + +import net.minecraftforge.fluids.FluidStack; + +public class SqueezerRecipe implements ISqueezerRecipe { + + private final int processingTime; + private final ItemStack[] resources; + private final FluidStack fluidOutput; + private final ItemStack remnants; + private final float remnantsChance; + + public SqueezerRecipe(int processingTime, ItemStack[] resources, FluidStack fluidOutput, ItemStack remnants, float remnantsChance) { + this.processingTime = processingTime; + this.resources = resources; + this.fluidOutput = fluidOutput; + this.remnants = remnants; + this.remnantsChance = remnantsChance; + } + + @Override + public ItemStack[] getResources() { + return resources; + } + + @Override + public ItemStack getRemnants() { + return remnants; + } + + @Override + public float getRemnantsChance() { + return remnantsChance; + } + + @Override + public FluidStack getFluidOutput() { + return fluidOutput; + } + + @Override + public int getProcessingTime() { + return processingTime; + } + +} diff --git a/src/main/java/forestry/factory/recipes/CraftGuideBottler.java b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideBottler.java old mode 100755 new mode 100644 similarity index 97% rename from src/main/java/forestry/factory/recipes/CraftGuideBottler.java rename to src/main/java/forestry/factory/recipes/craftguide/CraftGuideBottler.java index 25f832e8a..7f1c622a8 --- a/src/main/java/forestry/factory/recipes/CraftGuideBottler.java +++ b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideBottler.java @@ -8,7 +8,7 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.factory.recipes; +package forestry.factory.recipes.craftguide; import net.minecraft.item.ItemStack; diff --git a/src/main/java/forestry/factory/recipes/CraftGuideCarpenter.java b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideCarpenter.java old mode 100755 new mode 100644 similarity index 98% rename from src/main/java/forestry/factory/recipes/CraftGuideCarpenter.java rename to src/main/java/forestry/factory/recipes/craftguide/CraftGuideCarpenter.java index d48cd9863..5c73a3eb2 --- a/src/main/java/forestry/factory/recipes/CraftGuideCarpenter.java +++ b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideCarpenter.java @@ -8,7 +8,7 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.factory.recipes; +package forestry.factory.recipes.craftguide; import net.minecraft.item.ItemStack; diff --git a/src/main/java/forestry/factory/recipes/CraftGuideCentrifuge.java b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideCentrifuge.java old mode 100755 new mode 100644 similarity index 98% rename from src/main/java/forestry/factory/recipes/CraftGuideCentrifuge.java rename to src/main/java/forestry/factory/recipes/craftguide/CraftGuideCentrifuge.java index 583885777..54c65a5e2 --- a/src/main/java/forestry/factory/recipes/CraftGuideCentrifuge.java +++ b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideCentrifuge.java @@ -8,7 +8,7 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.factory.recipes; +package forestry.factory.recipes.craftguide; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/forestry/factory/recipes/CraftGuideCustomRecipes.java b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideCustomRecipes.java old mode 100755 new mode 100644 similarity index 97% rename from src/main/java/forestry/factory/recipes/CraftGuideCustomRecipes.java rename to src/main/java/forestry/factory/recipes/craftguide/CraftGuideCustomRecipes.java index 474d87ce5..84322eef5 --- a/src/main/java/forestry/factory/recipes/CraftGuideCustomRecipes.java +++ b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideCustomRecipes.java @@ -8,7 +8,7 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.factory.recipes; +package forestry.factory.recipes.craftguide; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; diff --git a/src/main/java/forestry/factory/recipes/CraftGuideFabricator.java b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideFabricator.java old mode 100755 new mode 100644 similarity index 98% rename from src/main/java/forestry/factory/recipes/CraftGuideFabricator.java rename to src/main/java/forestry/factory/recipes/craftguide/CraftGuideFabricator.java index c20ab4ac7..c577bac0e --- a/src/main/java/forestry/factory/recipes/CraftGuideFabricator.java +++ b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideFabricator.java @@ -8,7 +8,7 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.factory.recipes; +package forestry.factory.recipes.craftguide; import net.minecraft.item.ItemStack; diff --git a/src/main/java/forestry/factory/recipes/CraftGuideFermenter.java b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideFermenter.java old mode 100755 new mode 100644 similarity index 98% rename from src/main/java/forestry/factory/recipes/CraftGuideFermenter.java rename to src/main/java/forestry/factory/recipes/craftguide/CraftGuideFermenter.java index 80d4a8860..4d846c034 --- a/src/main/java/forestry/factory/recipes/CraftGuideFermenter.java +++ b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideFermenter.java @@ -8,7 +8,7 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.factory.recipes; +package forestry.factory.recipes.craftguide; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/forestry/factory/recipes/CraftGuideIntegration.java b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideIntegration.java old mode 100755 new mode 100644 similarity index 97% rename from src/main/java/forestry/factory/recipes/CraftGuideIntegration.java rename to src/main/java/forestry/factory/recipes/craftguide/CraftGuideIntegration.java index 322f13d4b..275f05f66 --- a/src/main/java/forestry/factory/recipes/CraftGuideIntegration.java +++ b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideIntegration.java @@ -8,7 +8,7 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.factory.recipes; +package forestry.factory.recipes.craftguide; import java.lang.reflect.Method; diff --git a/src/main/java/forestry/factory/recipes/CraftGuideSqueezer.java b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideSqueezer.java old mode 100755 new mode 100644 similarity index 80% rename from src/main/java/forestry/factory/recipes/CraftGuideSqueezer.java rename to src/main/java/forestry/factory/recipes/craftguide/CraftGuideSqueezer.java index 002792fca..0a1356659 --- a/src/main/java/forestry/factory/recipes/CraftGuideSqueezer.java +++ b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideSqueezer.java @@ -8,13 +8,14 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.factory.recipes; +package forestry.factory.recipes.craftguide; import net.minecraft.item.ItemStack; import forestry.core.config.Defaults; import forestry.core.config.ForestryBlock; import forestry.factory.gadgets.MachineSqueezer; +import forestry.factory.recipes.ISqueezerRecipe; import uristqwerty.CraftGuide.api.ChanceSlot; import uristqwerty.CraftGuide.api.ItemSlot; @@ -50,15 +51,15 @@ public class CraftGuideSqueezer implements RecipeProvider { ItemStack machine = ForestryBlock.factoryTESR.getItemStack(1, Defaults.DEFINITION_SQUEEZER_META); RecipeTemplate template = generator.createRecipeTemplate(slots, machine); - for (MachineSqueezer.Recipe recipe : MachineSqueezer.RecipeManager.recipes) { + for (ISqueezerRecipe recipe : MachineSqueezer.RecipeManager.recipes) { Object[] array = new Object[12]; - System.arraycopy(recipe.resources, 0, array, 0, recipe.resources.length); - if (recipe.remnants != null) { - array[9] = recipe.chance > 0 ? new Object[]{recipe.remnants.copy(), recipe.chance} : null; + System.arraycopy(recipe.getResources(), 0, array, 0, recipe.getResources().length); + if (recipe.getRemnants() != null) { + array[9] = recipe.getRemnantsChance() > 0 ? new Object[]{recipe.getRemnants().copy(), recipe.getRemnantsChance()} : null; } - if (recipe.liquid != null) { - array[10] = recipe.liquid; + if (recipe.getFluidOutput() != null) { + array[10] = recipe.getFluidOutput(); } array[11] = machine; generator.addRecipe(template, array); diff --git a/src/main/java/forestry/factory/recipes/CraftGuideStill.java b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideStill.java old mode 100755 new mode 100644 similarity index 97% rename from src/main/java/forestry/factory/recipes/CraftGuideStill.java rename to src/main/java/forestry/factory/recipes/craftguide/CraftGuideStill.java index 52dcbeecf..6f6e2de64 --- a/src/main/java/forestry/factory/recipes/CraftGuideStill.java +++ b/src/main/java/forestry/factory/recipes/craftguide/CraftGuideStill.java @@ -8,7 +8,7 @@ * Various Contributors including, but not limited to: * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges ******************************************************************************/ -package forestry.factory.recipes; +package forestry.factory.recipes.craftguide; import net.minecraft.item.ItemStack; diff --git a/src/main/java/forestry/factory/recipes/nei/INBTMatchingCachedRecipe.java b/src/main/java/forestry/factory/recipes/nei/INBTMatchingCachedRecipe.java new file mode 100644 index 000000000..034480fad --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/INBTMatchingCachedRecipe.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import codechicken.nei.PositionedStack; + +public interface INBTMatchingCachedRecipe { + Iterable getIngredients(); + + boolean preservesNBT(); + + PositionedStack getResult(); +} diff --git a/src/main/java/forestry/factory/recipes/nei/IRecipeHandlerBase.java b/src/main/java/forestry/factory/recipes/nei/IRecipeHandlerBase.java new file mode 100644 index 000000000..d64122d35 --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/IRecipeHandlerBase.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import codechicken.nei.recipe.ICraftingHandler; +import codechicken.nei.recipe.IUsageHandler; + +public interface IRecipeHandlerBase extends ICraftingHandler, IUsageHandler { + void prepare(); +} diff --git a/src/main/java/forestry/factory/recipes/nei/NEIHandlerBottler.java b/src/main/java/forestry/factory/recipes/nei/NEIHandlerBottler.java new file mode 100644 index 000000000..fffda6784 --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/NEIHandlerBottler.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.awt.Point; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.StatCollector; + +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidStack; + +import forestry.factory.gadgets.MachineBottler; +import forestry.factory.gui.GuiBottler; + +import codechicken.lib.gui.GuiDraw; +import codechicken.nei.NEIServerUtils; +import codechicken.nei.PositionedStack; + +public class NEIHandlerBottler extends RecipeHandlerBase { + + private static List recipes = new ArrayList(); + + @Override + public void prepare() { + for (FluidContainerData container : FluidContainerRegistry.getRegisteredFluidContainerData()) { + MachineBottler.Recipe recipe = MachineBottler.RecipeManager.findMatchingRecipe(container.fluid, container.emptyContainer); + if (recipe != null) { + recipes.add(recipe); + } + } + } + + public class CachedBottlerRecipe extends CachedBaseRecipe { + + public PositionedFluidTank fluid; + public PositionedStack input; + public PositionedStack output; + + public CachedBottlerRecipe(MachineBottler.Recipe recipe) { + if (recipe.input != null) { + this.fluid = new PositionedFluidTank(recipe.input, 10000, new Rectangle(48, 6, 16, 58), NEIHandlerBottler.this.getGuiTexture(), new Point(176, 0)); + } + if (recipe.can != null) { + this.input = new PositionedStack(recipe.can, 111, 8); + } + if (recipe.bottled != null) { + this.output = new PositionedStack(recipe.bottled, 111, 44); + } + } + + @Override + public PositionedStack getIngredient() { + return this.input; + } + + @Override + public PositionedStack getResult() { + return this.output; + } + + @Override + public PositionedFluidTank getFluidTank() { + return this.fluid; + } + + } + + @Override + public String getRecipeID() { + return "forestry.bottler"; + } + + @Override + public String getRecipeName() { + return StatCollector.translateToLocal("tile.for.factory.0.name"); + } + + @Override + public String getGuiTexture() { + return "forestry:textures/gui/bottler.png"; + } + + @Override + public void loadTransferRects() { + this.addTransferRect(75, 27, 24, 17); + } + + @Override + public Class getGuiClass() { + return GuiBottler.class; + } + + @Override + public void drawBackground(int recipe) { + this.changeToGuiTexture(); + GuiDraw.drawTexturedModalRect(43, 0, 48, 11, 123, 65); + } + + @Override + public void drawExtras(int recipe) { + this.drawProgressBar(75, 27, 176, 74, 24, 17, 40, 0); + } + + @Override + public void loadAllRecipes() { + for (MachineBottler.Recipe recipe : recipes) { + this.arecipes.add(new CachedBottlerRecipe(recipe)); + } + } + + @Override + public void loadCraftingRecipes(ItemStack result) { + for (MachineBottler.Recipe recipe : recipes) { + if (NEIServerUtils.areStacksSameTypeCrafting(recipe.bottled, result)) { + this.arecipes.add(new CachedBottlerRecipe(recipe)); + } + } + } + + @Override + public void loadUsageRecipes(ItemStack ingred) { + super.loadUsageRecipes(ingred); + for (MachineBottler.Recipe recipe : recipes) { + if (NEIServerUtils.areStacksSameTypeCrafting(recipe.can, ingred)) { + this.arecipes.add(new CachedBottlerRecipe(recipe)); + } + } + } + + @Override + public void loadUsageRecipes(FluidStack ingred) { + for (MachineBottler.Recipe recipe : recipes) { + if (NEIUtils.areFluidsSameType(recipe.input, ingred)) { + this.arecipes.add(new CachedBottlerRecipe(recipe)); + } + } + } + +} diff --git a/src/main/java/forestry/factory/recipes/nei/NEIHandlerCarpenter.java b/src/main/java/forestry/factory/recipes/nei/NEIHandlerCarpenter.java new file mode 100644 index 000000000..a2ab04d7f --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/NEIHandlerCarpenter.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.awt.Point; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.StatCollector; + +import net.minecraftforge.fluids.FluidStack; + +import forestry.core.interfaces.IDescriptiveRecipe; +import forestry.factory.gadgets.MachineCarpenter; +import forestry.factory.gui.GuiCarpenter; + +import codechicken.lib.gui.GuiDraw; +import codechicken.nei.NEIServerUtils; +import codechicken.nei.PositionedStack; +import codechicken.nei.api.API; + +public class NEIHandlerCarpenter extends RecipeHandlerBase { + + private static Class guiClass; + + @Override + public void prepare() { + guiClass = GuiCarpenter.class; + API.setGuiOffset(guiClass, 5, 14); + } + + public class CachedCarpenterRecipe extends CachedBaseRecipe { + + public List inputs = new ArrayList(); + public PositionedFluidTank tank; + public PositionedStack output; + + public CachedCarpenterRecipe(MachineCarpenter.Recipe recipe, boolean genPerms) { + IDescriptiveRecipe irecipe = (IDescriptiveRecipe) recipe.asIRecipe(); + if (irecipe != null) { + if (irecipe.getIngredients() != null) { + this.setIngredients(irecipe.getWidth(), irecipe.getHeight(), irecipe.getIngredients()); + } + if (recipe.getBox() != null) { + this.inputs.add(new PositionedStack(recipe.getBox(), 78, 6)); + } + if (recipe.getLiquid() != null) { + this.tank = new PositionedFluidTank(recipe.getLiquid(), 10000, new Rectangle(145, 3, 16, 58), NEIHandlerCarpenter.this.getGuiTexture(), new Point(176, 0)); + } + if (recipe.getCraftingResult() != null) { + this.output = new PositionedStack(recipe.getCraftingResult(), 75, 37); + } + } + + if (genPerms) { + this.generatePermutations(); + } + } + + public CachedCarpenterRecipe(MachineCarpenter.Recipe recipe) { + this(recipe, false); + } + + public void setIngredients(int width, int height, Object[] items) { + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + Object item = items[y * width + x]; + if (item == null) { + continue; + } else if (item instanceof ItemStack[] && ((ItemStack[]) item).length == 0) { + continue; + } else if (item instanceof List && ((List) item).size() == 0) { + continue; + } + + PositionedStack stack = new PositionedStack(item, 5 + x * 18, 6 + y * 18, false); + stack.setMaxSize(1); + this.inputs.add(stack); + } + } + } + + @Override + public List getIngredients() { + return this.getCycledIngredients(NEIHandlerCarpenter.this.cycleticks / 20, this.inputs); + } + + @Override + public PositionedFluidTank getFluidTank() { + return this.tank; + } + + @Override + public PositionedStack getResult() { + return this.output; + } + + public void generatePermutations() { + for (PositionedStack p : this.inputs) { + p.generatePermutations(); + } + } + + } + + @Override + public String getRecipeID() { + return "forestry.carpenter"; + } + + @Override + public String getRecipeName() { + return StatCollector.translateToLocal("tile.for.factory.1.name"); + } + + @Override + public String getGuiTexture() { + return "forestry:textures/gui/carpenter.png"; + } + + @Override + public void loadTransferRects() { + this.addTransferRect(93, 36, 4, 18); + } + + @Override + public Class getGuiClass() { + return guiClass; + } + + @Override + public void drawBackground(int recipe) { + this.changeToGuiTexture(); + GuiDraw.drawTexturedModalRect(0, 0, 5, 14, 166, 65); + } + + @Override + public void drawExtras(int recipe) { + this.drawProgressBar(93, 36, 176, 59, 4, 17, 80, 3); + } + + @Override + public void loadAllRecipes() { + for (MachineCarpenter.Recipe recipe : MachineCarpenter.RecipeManager.recipes) { + this.arecipes.add(new CachedCarpenterRecipe(recipe, true)); + } + } + + @Override + public void loadCraftingRecipes(ItemStack result) { + for (MachineCarpenter.Recipe recipe : MachineCarpenter.RecipeManager.recipes) { + if (NEIServerUtils.areStacksSameTypeCrafting(recipe.getCraftingResult(), result)) { + this.arecipes.add(new CachedCarpenterRecipe(recipe, true)); + } + } + } + + @Override + public void loadUsageRecipes(ItemStack ingred) { + super.loadUsageRecipes(ingred); + for (MachineCarpenter.Recipe recipe : MachineCarpenter.RecipeManager.recipes) { + CachedCarpenterRecipe crecipe = new CachedCarpenterRecipe(recipe); + if (crecipe.inputs != null && crecipe.contains(crecipe.inputs, ingred)) { + crecipe.generatePermutations(); + crecipe.setIngredientPermutation(crecipe.inputs, ingred); + this.arecipes.add(crecipe); + } + } + } + + @Override + public void loadUsageRecipes(FluidStack ingredient) { + for (MachineCarpenter.Recipe recipe : MachineCarpenter.RecipeManager.recipes) { + if (NEIUtils.areFluidsSameType(recipe.getLiquid(), ingredient)) { + this.arecipes.add(new CachedCarpenterRecipe(recipe, true)); + } + } + } + +} diff --git a/src/main/java/forestry/factory/recipes/nei/NEIHandlerCentrifuge.java b/src/main/java/forestry/factory/recipes/nei/NEIHandlerCentrifuge.java new file mode 100644 index 000000000..be61c031b --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/NEIHandlerCentrifuge.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.PriorityQueue; +import java.util.Set; + +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.StatCollector; + +import forestry.api.recipes.ICentrifugeRecipe; +import forestry.factory.gadgets.MachineCentrifuge; +import forestry.factory.gui.GuiCentrifuge; + +import codechicken.nei.NEIServerUtils; +import codechicken.nei.PositionedStack; + +public class NEIHandlerCentrifuge extends RecipeHandlerBase { + + private static final int[][] OUTPUTS = new int[][]{{0, 0}, {1, 0}, {2, 0}, {0, 1}, {1, 1}, {2, 1}, {0, 2}, {1, 2}, {2, 2}}; + + private static final Comparator> highestChanceComparator = new Comparator>() { + @Override + public int compare(Entry o1, Entry o2) { + return o2.getValue().compareTo(o1.getValue()); + } + }; + + public class CachedCentrifugeRecipe extends CachedBaseRecipe { + + public PositionedStack inputs; + public List outputs = new ArrayList(); + + public CachedCentrifugeRecipe(ICentrifugeRecipe recipe, boolean genPerms) { + if (recipe.getInput() != null) { + this.inputs = new PositionedStack(recipe.getInput(), 25, 26); + } + if (recipe.getAllProducts() != null) { + this.setResults(recipe.getAllProducts()); + } + } + + public CachedCentrifugeRecipe(ICentrifugeRecipe recipe) { + this(recipe, false); + } + + public void setResults(Map outputs) { + Set> entrySet = outputs.entrySet(); + if (entrySet.size() == 0) { + return; + } + PriorityQueue> sortByChance = new PriorityQueue>(entrySet.size(), highestChanceComparator); + sortByChance.addAll(entrySet); + + int i = 0; + while (!sortByChance.isEmpty()) { + Entry stack = sortByChance.poll(); + if (i >= OUTPUTS.length) { + return; + } + PositionedStackAdv output = new PositionedStackAdv(stack.getKey(), 93 + OUTPUTS[i][0] * 18, 8 + OUTPUTS[i][1] * 18); + output.setChance(stack.getValue()); + this.outputs.add(output); + i++; + } + } + + @Override + public PositionedStack getIngredient() { + this.randomRenderPermutation(this.inputs, NEIHandlerCentrifuge.this.cycleticks / 20); + return this.inputs; + } + + @Override + public List getOtherStacks() { + return this.outputs; + } + + @Override + public PositionedStack getResult() { + return null; + } + + } + + @Override + public String getRecipeID() { + return "forestry.centrifuge"; + } + + @Override + public String getRecipeName() { + return StatCollector.translateToLocal("tile.for.factory.2.name"); + } + + @Override + public String getGuiTexture() { + return "forestry:textures/gui/centrifugesocket.png"; + } + + @Override + public void loadTransferRects() { + this.addTransferRect(57 - 12, 26 - 8, 16, 24 + 6 + 6); + } + + @Override + public Class getGuiClass() { + return GuiCentrifuge.class; + } + + @Override + public void drawExtras(int recipe) { + this.drawProgressBar(57 - 4, 25, 176, 0, 4, 17, 80, 3); + } + + @Override + public void loadAllRecipes() { + for (ICentrifugeRecipe recipe : MachineCentrifuge.RecipeManager.recipes) { + this.arecipes.add(new CachedCentrifugeRecipe(recipe, true)); + } + } + + @Override + public void loadCraftingRecipes(ItemStack result) { + for (ICentrifugeRecipe recipe : MachineCentrifuge.RecipeManager.recipes) { + CachedCentrifugeRecipe crecipe = new CachedCentrifugeRecipe(recipe); + if (crecipe.outputs != null && crecipe.contains(crecipe.outputs, result)) { + crecipe.setIngredientPermutation(crecipe.outputs, result); + this.arecipes.add(crecipe); + } + } + } + + @Override + public void loadUsageRecipes(ItemStack ingred) { + super.loadCraftingRecipes(ingred); + for (ICentrifugeRecipe recipe : MachineCentrifuge.RecipeManager.recipes) { + if (NEIServerUtils.areStacksSameTypeCrafting(recipe.getInput(), ingred)) { + this.arecipes.add(new CachedCentrifugeRecipe(recipe, true)); + } + } + } + +} diff --git a/src/main/java/forestry/factory/recipes/nei/NEIHandlerFabricator.java b/src/main/java/forestry/factory/recipes/nei/NEIHandlerFabricator.java new file mode 100644 index 000000000..31ad39018 --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/NEIHandlerFabricator.java @@ -0,0 +1,258 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.awt.Point; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; + +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; + +import forestry.api.recipes.IFabricatorRecipe; +import forestry.factory.gadgets.MachineFabricator; +import forestry.factory.gui.GuiFabricator; + +import codechicken.nei.NEIServerUtils; +import codechicken.nei.PositionedStack; +import codechicken.nei.recipe.GuiRecipe; + +public class NEIHandlerFabricator extends RecipeHandlerBase { + + public class CachedFabricatorRecipe extends CachedBaseRecipe implements INBTMatchingCachedRecipe { + + private final boolean preservesNbt; + + public List smeltingInput = new ArrayList(); + public PositionedFluidTank tank; + public List inputs = new ArrayList(); + public PositionedStack output; + + public CachedFabricatorRecipe(IFabricatorRecipe recipe, boolean genPerms) { + this.preservesNbt = recipe.preservesNbt(); + if (recipe.getLiquid() != null) { + this.tank = new PositionedFluidTank(recipe.getLiquid(), 2000, new Rectangle(21, 37, 16, 16)); + List smeltingInput = new ArrayList(); + for (MachineFabricator.Smelting s : getSmeltingInputs().get(recipe.getLiquid().getFluid())) { + smeltingInput.add(s.getResource()); + } + if (!smeltingInput.isEmpty()) { + this.smeltingInput.add(new PositionedStack(smeltingInput, 21, 10)); + } + } + + if (recipe != null) { + if (recipe.getIngredients() != null) { + this.setIngredients(recipe.getWidth(), recipe.getHeight(), recipe.getIngredients()); + } + if (recipe.getPlan() != null) { + this.inputs.add(new PositionedStack(recipe.getPlan(), 134, 6)); + } + + if (recipe.getRecipeOutput() != null) { + this.output = new PositionedStack(recipe.getRecipeOutput(), 134, 42); + } + } + + if (genPerms) { + this.generatePermutations(); + } + } + + public CachedFabricatorRecipe(IFabricatorRecipe recipe) { + this(recipe, false); + } + + public void setIngredients(int width, int height, Object[] items) { + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + Object item = items[y * width + x]; + if (item == null) { + continue; + } else if (item instanceof ItemStack[] && ((ItemStack[]) item).length == 0) { + continue; + } else if (item instanceof List && ((List) item).size() == 0) { + continue; + } + + PositionedStack stack = new PositionedStack(item, 62 + x * 18, 6 + y * 18, false); + stack.setMaxSize(1); + this.inputs.add(stack); + } + } + } + + @Override + public List getCycledIngredients(int cycle, List ingredients) { + if (preservesNbt) { + // cycle ingredients and output together + Random random = new Random(cycle); + cycle = Math.abs(random.nextInt()); + NBTTagCompound nbt = null; + for (PositionedStack ingredient : ingredients) { + ingredient.setPermutationToRender(cycle % ingredient.items.length); + if (ingredient.item.hasTagCompound()) { + nbt = ingredient.item.getTagCompound(); + } + } + output.setPermutationToRender(cycle % output.items.length); + if (nbt != null) { + output.item.setTagCompound((NBTTagCompound) nbt.copy()); + } + } else { + return super.getCycledIngredients(cycle, ingredients); + } + + return ingredients; + } + + @Override + public boolean preservesNBT() { + return preservesNbt; + } + + @Override + public PositionedStack getResult() { + return this.output; + } + + @Override + public List getIngredients() { + return getCycledIngredients(NEIHandlerFabricator.this.cycleticks / 20, this.inputs); + } + + @Override + public PositionedFluidTank getFluidTank() { + return this.tank; + } + + public void generatePermutations() { + for (PositionedStack p : this.inputs) { + p.generatePermutations(); + } + } + + } + + @Override + public List getIngredientStacks(int recipe) { + return arecipes.get(recipe).getIngredients(); + } + + @Override + public PositionedStack getResultStack(int recipe) { + return arecipes.get(recipe).getResult(); + } + + @Override + public String getRecipeID() { + return "forestry.fabricator"; + } + + @Override + public String getRecipeName() { + return StatCollector.translateToLocal("tile.for.factory2.0.name"); + } + + @Override + public String getGuiTexture() { + return "forestry:textures/gui/fabricator.png"; + } + + @Override + public void loadTransferRects() { + this.addTransferRect(117, 44, 14, 13); + } + + @Override + public Class getGuiClass() { + return GuiFabricator.class; + } + + @Override + public void loadAllRecipes() { + for (IFabricatorRecipe recipe : MachineFabricator.RecipeManager.recipes) { + this.arecipes.add(new CachedFabricatorRecipe(recipe, true)); + } + } + + @Override + public void loadCraftingRecipes(ItemStack result) { + for (IFabricatorRecipe recipe : MachineFabricator.RecipeManager.recipes) { + if (NEIServerUtils.areStacksSameTypeCrafting(recipe.getRecipeOutput(), result)) { + CachedFabricatorRecipe crecipe = new CachedFabricatorRecipe(recipe, true); + NEIUtils.setResultPermutationNBT(crecipe, result); + this.arecipes.add(crecipe); + } + } + } + + @Override + public void loadUsageRecipes(ItemStack ingred) { + super.loadUsageRecipes(ingred); + for (IFabricatorRecipe recipe : MachineFabricator.RecipeManager.recipes) { + CachedFabricatorRecipe crecipe = new CachedFabricatorRecipe(recipe); + if (crecipe.inputs != null && crecipe.contains(crecipe.inputs, ingred) || crecipe.smeltingInput != null && crecipe.contains(crecipe.smeltingInput, ingred)) { + crecipe.generatePermutations(); + NEIUtils.setIngredientPermutationNBT(crecipe, ingred); + crecipe.setIngredientPermutation(crecipe.smeltingInput, ingred); + this.arecipes.add(crecipe); + } + } + } + + @Override + public void loadUsageRecipes(FluidStack ingredient) { + for (IFabricatorRecipe recipe : MachineFabricator.RecipeManager.recipes) { + if (NEIUtils.areFluidsSameType(recipe.getLiquid(), ingredient)) { + this.arecipes.add(new CachedFabricatorRecipe(recipe, true)); + } + } + } + + @Override + public List provideItemTooltip(GuiRecipe guiRecipe, ItemStack itemStack, List currenttip, CachedBaseRecipe crecipe, Point relMouse) { + super.provideItemTooltip(guiRecipe, itemStack, currenttip, crecipe, relMouse); + + if (new Rectangle(20, 9, 18, 18).contains(relMouse)) { + for (MachineFabricator.Smelting smelting : MachineFabricator.RecipeManager.smeltings) { + if (NEIServerUtils.areStacksSameTypeCrafting(smelting.getResource(), itemStack) && smelting.getProduct() != null) { + currenttip.add(EnumChatFormatting.GRAY.toString() + NEIUtils.translate("handler.forestry.fabricator.worth") + " " + smelting.getProduct().amount + " mB"); + } + } + } + + return currenttip; + } + + private static Map> getSmeltingInputs() { + Map> smeltingInputs = new HashMap>(); + for (MachineFabricator.Smelting smelting : MachineFabricator.RecipeManager.smeltings) { + Fluid fluid = smelting.getProduct().getFluid(); + if (!smeltingInputs.containsKey(fluid)) { + smeltingInputs.put(fluid, new ArrayList()); + } + smeltingInputs.get(fluid).add(smelting); + } + return smeltingInputs; + } + +} diff --git a/src/main/java/forestry/factory/recipes/nei/NEIHandlerFermenter.java b/src/main/java/forestry/factory/recipes/nei/NEIHandlerFermenter.java new file mode 100644 index 000000000..26037e397 --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/NEIHandlerFermenter.java @@ -0,0 +1,205 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.awt.Point; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.StatCollector; + +import net.minecraftforge.fluids.FluidStack; + +import forestry.api.fuels.FermenterFuel; +import forestry.api.fuels.FuelManager; +import forestry.api.recipes.IVariableFermentable; +import forestry.factory.gadgets.MachineFermenter; +import forestry.factory.gui.GuiFermenter; + +import codechicken.lib.gui.GuiDraw; +import codechicken.nei.NEIServerUtils; +import codechicken.nei.PositionedStack; +import codechicken.nei.api.API; + +public class NEIHandlerFermenter extends RecipeHandlerBase { + + private static Class guiClass; + + @Override + public void prepare() { + guiClass = GuiFermenter.class; + API.setGuiOffset(guiClass, 5, 15); + } + + public class CachedFermenterRecipe extends CachedBaseRecipe implements INBTMatchingCachedRecipe { + + public List tanks = new ArrayList(); + public PositionedStack resource; + public List inputItems = new ArrayList(); + + public CachedFermenterRecipe(MachineFermenter.Recipe recipe, ItemStack fermentable, boolean genPerms) { + if (recipe.liquid != null) { + FluidStack input = recipe.liquid.copy(); + input.amount = recipe.fermentationValue; + this.tanks.add(new PositionedFluidTank(input, 10000, new Rectangle(30, 4, 16, 58), NEIHandlerFermenter.this.getGuiTexture(), new Point(176, 0))); + } + if (recipe.output != null) { + FluidStack output = recipe.output.copy(); + if (fermentable.getItem() instanceof IVariableFermentable) { + output.amount = (int) (recipe.fermentationValue * recipe.modifier * ((IVariableFermentable) fermentable.getItem()).getFermentationModifier(fermentable)); + } else { + output.amount = (int) (recipe.fermentationValue * recipe.modifier); + } + this.tanks.add(new PositionedFluidTank(output, 10000, new Rectangle(120, 4, 16, 58), NEIHandlerFermenter.this.getGuiTexture(), new Point(176, 0))); + } + + this.inputItems.add(new PositionedStack(fermentable, 80, 8)); + List fuels = new ArrayList(); + for (FermenterFuel fuel : FuelManager.fermenterFuel.values()) { + fuels.add(fuel.item); + } + this.inputItems.add(new PositionedStack(fuels, 70, 42)); + + if (genPerms) { + this.generatePermutations(); + } + } + + @Override + public List getIngredients() { + return this.getCycledIngredients(NEIHandlerFermenter.this.cycleticks / 40, this.inputItems); + } + + @Override + public boolean preservesNBT() { + return false; + } + + @Override + public PositionedStack getResult() { + return null; + } + + @Override + public List getFluidTanks() { + return this.tanks; + } + + public void generatePermutations() { + for (PositionedStack p : this.inputItems) { + p.generatePermutations(); + } + } + + } + + @Override + public String getRecipeID() { + return "forestry.fermenter"; + } + + @Override + public String getRecipeName() { + return StatCollector.translateToLocal("tile.for.factory.3.name"); + } + + @Override + public String getGuiTexture() { + return "forestry:textures/gui/fermenter.png"; + } + + @Override + public void loadTransferRects() { + this.addTransferRect(76, 27, 14, 12); + } + + @Override + public Class getGuiClass() { + return guiClass; + } + + @Override + public void drawBackground(int recipe) { + this.changeToGuiTexture(); + GuiDraw.drawTexturedModalRect(25, 0, 30, 15, 116, 65); + } + + @Override + public void drawExtras(int recipe) { + this.drawProgressBar(69, 17, 176, 60, 4, 18, 40, 11); + this.drawProgressBar(93, 31, 176, 78, 4, 18, 80, 11); + } + + private List getCachedRecipes(MachineFermenter.Recipe recipe, boolean generatePermutations) { + if (recipe.resource != null && recipe.resource.getItem() instanceof IVariableFermentable) { + List crecipes = new ArrayList(); + for (ItemStack stack : NEIUtils.getItemVariations(recipe.resource)) { + crecipes.add(new CachedFermenterRecipe(recipe, stack, generatePermutations)); + } + return crecipes; + } + return Collections.singletonList(new CachedFermenterRecipe(recipe, recipe.resource, generatePermutations)); + } + + @Override + public void loadAllRecipes() { + for (MachineFermenter.Recipe recipe : MachineFermenter.RecipeManager.recipes) { + this.arecipes.addAll(this.getCachedRecipes(recipe, true)); + } + } + + @Override + public void loadCraftingRecipes(FluidStack result) { + for (MachineFermenter.Recipe recipe : MachineFermenter.RecipeManager.recipes) { + if (NEIUtils.areFluidsSameType(recipe.output, result)) { + this.arecipes.addAll(this.getCachedRecipes(recipe, true)); + } + } + } + + @Override + public void loadUsageRecipes(ItemStack ingred) { + super.loadUsageRecipes(ingred); + for (MachineFermenter.Recipe recipe : MachineFermenter.RecipeManager.recipes) { + if (recipe.resource != null) { + for (ItemStack stack : NEIUtils.getItemVariations(recipe.resource)) { + if (stack.hasTagCompound() && NEIServerUtils.areStacksSameType(stack, ingred) || !stack.hasTagCompound() && NEIServerUtils.areStacksSameTypeCrafting(stack, ingred)) { + CachedFermenterRecipe crecipe = new CachedFermenterRecipe(recipe, stack, true); + NEIUtils.setIngredientPermutationNBT(crecipe, ingred); + this.arecipes.add(crecipe); + } + } + } + for (FermenterFuel fuel : FuelManager.fermenterFuel.values()) { + if (NEIServerUtils.areStacksSameTypeCrafting(fuel.item, ingred)) { + for (CachedFermenterRecipe crecipe : this.getCachedRecipes(recipe, true)) { + crecipe.setIngredientPermutation(crecipe.inputItems, ingred); + this.arecipes.add(crecipe); + } + } + } + } + } + + @Override + public void loadUsageRecipes(FluidStack ingred) { + for (MachineFermenter.Recipe recipe : MachineFermenter.RecipeManager.recipes) { + if (NEIUtils.areFluidsSameType(recipe.liquid, ingred)) { + this.arecipes.addAll(this.getCachedRecipes(recipe, true)); + } + } + } + +} diff --git a/src/main/java/forestry/factory/recipes/nei/NEIHandlerMoistener.java b/src/main/java/forestry/factory/recipes/nei/NEIHandlerMoistener.java new file mode 100644 index 000000000..6975d781d --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/NEIHandlerMoistener.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.awt.Point; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.StatCollector; + +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import forestry.api.fuels.FuelManager; +import forestry.api.fuels.MoistenerFuel; +import forestry.factory.gadgets.MachineMoistener; +import forestry.factory.gui.GuiMoistener; + +import codechicken.nei.NEIServerUtils; +import codechicken.nei.PositionedStack; + +public class NEIHandlerMoistener extends RecipeHandlerBase { + + public class CachedMoistenerRecipe extends CachedBaseRecipe { + + public PositionedFluidTank tank; + public List fuels = new ArrayList(); + public PositionedStack input; + public PositionedStack output; + + public CachedMoistenerRecipe(MachineMoistener.Recipe recipe, MoistenerFuel fuel) { + this.tank = new PositionedFluidTank(FluidRegistry.getFluidStack("water", 10000), 10000, new Rectangle(11, 5, 16, 58), NEIHandlerMoistener.this.getGuiTexture(), new Point(176, 0)); + this.tank.showAmount = false; + if (fuel.item != null) { + this.fuels.add(new PositionedStack(fuel.item, 34, 47)); + } + if (fuel.product != null) { + this.fuels.add(new PositionedStack(fuel.product, 100, 26)); + } + if (recipe.resource != null) { + this.input = new PositionedStack(recipe.resource, 138, 8); + } + if (recipe.product != null) { + this.output = new PositionedStack(recipe.product, 138, 44); + } + } + + @Override + public List getOtherStacks() { + return this.fuels; + } + + @Override + public PositionedStack getIngredient() { + return this.input; + } + + @Override + public PositionedStack getResult() { + return this.output; + } + + @Override + public PositionedFluidTank getFluidTank() { + return this.tank; + } + + } + + @Override + public String getRecipeID() { + return "forestry.moistener"; + } + + @Override + public String getRecipeName() { + return StatCollector.translateToLocal("tile.for.factory.4.name"); + } + + @Override + public String getGuiTexture() { + return "forestry:textures/gui/moistener.png"; + } + + @Override + public void loadTransferRects() { + this.addTransferRect(138, 27, 16, 14); + } + + @Override + public Class getGuiClass() { + return GuiMoistener.class; + } + + @Override + public void drawBackground(int recipe) { + super.drawBackground(recipe); + this.drawProgressBar(88, 6, 176, 91, 29, 55, 80, 3); + } + + @Override + public void drawExtras(int recipe) { + this.drawProgressBar(119, 25, 176, 74, 16, 15, 160, 0); + } + + @Override + public void loadAllRecipes() { + for (MachineMoistener.Recipe recipe : MachineMoistener.RecipeManager.recipes) { + for (MoistenerFuel fuel : FuelManager.moistenerResource.values()) { + this.arecipes.add(new CachedMoistenerRecipe(recipe, fuel)); + } + } + } + + @Override + public void loadCraftingRecipes(ItemStack result) { + for (MachineMoistener.Recipe recipe : MachineMoistener.RecipeManager.recipes) { + for (MoistenerFuel fuel : FuelManager.moistenerResource.values()) { + if (NEIServerUtils.areStacksSameTypeCrafting(recipe.product, result) || NEIServerUtils.areStacksSameTypeCrafting(fuel.product, result)) { + this.arecipes.add(new CachedMoistenerRecipe(recipe, fuel)); + } + } + } + } + + @Override + public void loadUsageRecipes(ItemStack ingred) { + super.loadUsageRecipes(ingred); + for (MachineMoistener.Recipe recipe : MachineMoistener.RecipeManager.recipes) { + for (MoistenerFuel fuel : FuelManager.moistenerResource.values()) { + if (NEIServerUtils.areStacksSameTypeCrafting(recipe.resource, ingred) || NEIServerUtils.areStacksSameTypeCrafting(fuel.item, ingred)) { + this.arecipes.add(new CachedMoistenerRecipe(recipe, fuel)); + } + } + } + } + + @Override + public void loadUsageRecipes(FluidStack ingredient) { + if (ingredient.getFluid() == FluidRegistry.WATER) { + this.loadAllRecipes(); + } + } + +} diff --git a/src/main/java/forestry/factory/recipes/nei/NEIHandlerShapedCustom.java b/src/main/java/forestry/factory/recipes/nei/NEIHandlerShapedCustom.java new file mode 100644 index 000000000..55fb47de5 --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/NEIHandlerShapedCustom.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; + +import forestry.core.utils.ShapedRecipeCustom; + +import codechicken.nei.NEIServerUtils; +import codechicken.nei.PositionedStack; + +public class NEIHandlerShapedCustom extends RecipeHandlerBase { + + public class CachedShapedCustomRecipe extends CachedBaseRecipe implements INBTMatchingCachedRecipe { + private final boolean preservesNbt; + + public List inputs = new ArrayList(); + public PositionedStack output; + + public CachedShapedCustomRecipe(ShapedRecipeCustom recipe) { + if (recipe.getIngredients() != null && recipe.getIngredients().length > 0) { + this.setIngredients(recipe.getWidth(), recipe.getHeight(), recipe.getIngredients()); + } + if (recipe.getRecipeOutput() != null) { + ItemStack output = recipe.getRecipeOutput(); + this.output = new PositionedStack(output, 119, 24); + } + this.preservesNbt = recipe.preservesNbt(); + } + + public void setIngredients(int width, int height, Object[] items) { + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + if (items.length <= y * width + x) { + continue; + } + + Object item = items[y * width + x]; + if (item == null) { + continue; + } else if (item instanceof ItemStack[] && ((ItemStack[]) item).length == 0) { + continue; + } else if (item instanceof List && ((List) item).size() == 0) { + continue; + } + + PositionedStack stack = new PositionedStack(item, 25 + x * 18, 6 + y * 18); + stack.setMaxSize(1); + this.inputs.add(stack); + } + } + } + + @Override + public List getIngredients() { + return this.getCycledIngredients(NEIHandlerShapedCustom.this.cycleticks / 20, this.inputs); + } + + @Override + public boolean preservesNBT() { + return preservesNbt; + } + + @Override + public PositionedStack getResult() { + return this.output; + } + + } + + @Override + public void loadCraftingRecipes(ItemStack result) { + for (Object recipe : CraftingManager.getInstance().getRecipeList()) { + if (recipe instanceof ShapedRecipeCustom && NEIServerUtils.areStacksSameTypeCrafting(((ShapedRecipeCustom) recipe).getRecipeOutput(), result)) { + CachedShapedCustomRecipe crecipe = new CachedShapedCustomRecipe((ShapedRecipeCustom) recipe); + NEIUtils.setResultPermutationNBT(crecipe, result); + this.arecipes.add(crecipe); + } + } + } + + @Override + public void loadUsageRecipes(ItemStack ingredient) { + for (Object recipe : CraftingManager.getInstance().getRecipeList()) { + if (recipe instanceof ShapedRecipeCustom) { + CachedShapedCustomRecipe crecipe = new CachedShapedCustomRecipe((ShapedRecipeCustom) recipe); + if (crecipe.inputs != null && crecipe.contains(crecipe.inputs, ingredient)) { + NEIUtils.setIngredientPermutationNBT(crecipe, ingredient); + this.arecipes.add(crecipe); + } + } + } + } + + @Override + public String getRecipeID() { + return "crafting"; + } + + @Override + public String getRecipeName() { + return NEIUtils.translate("handler.forestry.shaped"); + } + + @Override + public String getGuiTexture() { + return "minecraft:textures/gui/container/crafting_table.png"; + } + +} diff --git a/src/main/java/forestry/factory/recipes/nei/NEIHandlerShapelessCustom.java b/src/main/java/forestry/factory/recipes/nei/NEIHandlerShapelessCustom.java new file mode 100644 index 000000000..9a40601f1 --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/NEIHandlerShapelessCustom.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; + +import forestry.core.utils.ShapelessRecipeCustom; + +import codechicken.nei.NEIServerUtils; +import codechicken.nei.PositionedStack; + +public class NEIHandlerShapelessCustom extends RecipeHandlerBase { + private static final int[][] OUTPUTS = new int[][]{{0, 0}, {1, 0}, {2, 0}, {0, 1}, {1, 1}, {2, 1}, {0, 2}, {1, 2}, {2, 2}}; + + public class CachedShapelessCustomRecipe extends CachedBaseRecipe implements INBTMatchingCachedRecipe { + private final boolean preservesNbt; + + public List inputs = new ArrayList(); + public PositionedStack output; + + public CachedShapelessCustomRecipe(ShapelessRecipeCustom recipe) { + if (recipe.getIngredients() != null && recipe.getIngredients().size() > 0) { + this.setIngredients(recipe.getIngredients()); + } + if (recipe.getRecipeOutput() != null) { + ItemStack output = recipe.getRecipeOutput(); + this.output = new PositionedStack(output, 119, 24); + } + this.preservesNbt = recipe.preservesNbt(); + } + + public void setIngredients(List items) { + for (int i = 0; i < items.size(); i++) { + ItemStack item = items.get(i); + if (item == null) { + continue; + } + + PositionedStack stack = new PositionedStack(item, 25 + OUTPUTS[i][0] * 18, 6 + OUTPUTS[i][1] * 18); + stack.setMaxSize(1); + this.inputs.add(stack); + } + } + + @Override + public List getIngredients() { + return this.getCycledIngredients(NEIHandlerShapelessCustom.this.cycleticks / 20, this.inputs); + } + + @Override + public boolean preservesNBT() { + return preservesNbt; + } + + @Override + public PositionedStack getResult() { + return this.output; + } + + } + + @Override + public void loadCraftingRecipes(ItemStack result) { + for (Object recipe : CraftingManager.getInstance().getRecipeList()) { + if (recipe instanceof ShapelessRecipeCustom && NEIServerUtils.areStacksSameTypeCrafting(((ShapelessRecipeCustom) recipe).getRecipeOutput(), result)) { + CachedShapelessCustomRecipe crecipe = new CachedShapelessCustomRecipe((ShapelessRecipeCustom) recipe); + NEIUtils.setResultPermutationNBT(crecipe, result); + this.arecipes.add(crecipe); + } + } + } + + @Override + public void loadUsageRecipes(ItemStack ingredient) { + for (Object recipe : CraftingManager.getInstance().getRecipeList()) { + if (recipe instanceof ShapelessRecipeCustom) { + CachedShapelessCustomRecipe crecipe = new CachedShapelessCustomRecipe((ShapelessRecipeCustom) recipe); + if (crecipe.inputs != null && crecipe.contains(crecipe.inputs, ingredient)) { + NEIUtils.setIngredientPermutationNBT(crecipe, ingredient); + this.arecipes.add(crecipe); + } + } + } + } + + @Override + public String getRecipeID() { + return "crafting"; + } + + @Override + public String getRecipeName() { + return NEIUtils.translate("handler.forestry.shapeless"); + } + + @Override + public String getGuiTexture() { + return "minecraft:textures/gui/container/crafting_table.png"; + } +} diff --git a/src/main/java/forestry/factory/recipes/nei/NEIHandlerSqueezer.java b/src/main/java/forestry/factory/recipes/nei/NEIHandlerSqueezer.java new file mode 100644 index 000000000..83855efdd --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/NEIHandlerSqueezer.java @@ -0,0 +1,170 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.awt.Point; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.StatCollector; + +import net.minecraftforge.fluids.FluidStack; + +import forestry.factory.gadgets.MachineSqueezer; +import forestry.factory.gui.GuiSqueezer; +import forestry.factory.recipes.ISqueezerRecipe; + +import codechicken.nei.NEIServerUtils; +import codechicken.nei.PositionedStack; + +public class NEIHandlerSqueezer extends RecipeHandlerBase { + + private static final int[][] INPUTS = new int[][]{{0, 0}, {1, 0}, {2, 0}, {0, 1}, {1, 1}, {2, 1}, {0, 2}, {1, 2}, {2, 2}}; + + public class CachedSqueezerRecipe extends CachedBaseRecipe { + + public List inputs = new ArrayList(); + public PositionedFluidTank tank; + public PositionedStackAdv remnants = null; + public int processingTime; + + public CachedSqueezerRecipe(ISqueezerRecipe recipe, boolean genPerms) { + if (recipe.getResources() != null) { + this.setIngredients(recipe.getResources()); + } + if (recipe.getFluidOutput() != null) { + this.tank = new PositionedFluidTank(recipe.getFluidOutput(), 10000, new Rectangle(117, 7, 16, 58), NEIHandlerSqueezer.this.getGuiTexture(), new Point(176, 0)); + } + if (recipe.getRemnants() != null) { + this.remnants = new PositionedStackAdv(recipe.getRemnants(), 92, 49).setChance(recipe.getRemnantsChance()); + } + + this.processingTime = recipe.getProcessingTime(); + + if (genPerms) { + this.generatePermutations(); + } + } + + public CachedSqueezerRecipe(ISqueezerRecipe recipe) { + this(recipe, false); + } + + public void setIngredients(Object[] inputs) { + int i = 0; + for (Object stack : inputs) { + if (i >= INPUTS.length) { + return; + } + this.inputs.add(new PositionedStack(stack, 12 + INPUTS[i][0] * 18, 10 + INPUTS[i][1] * 18, false)); + i++; + } + } + + @Override + public List getIngredients() { + return this.getCycledIngredients(NEIHandlerSqueezer.this.cycleticks / 20, this.inputs); + } + + @Override + public PositionedFluidTank getFluidTank() { + return this.tank; + } + + @Override + public PositionedStack getResult() { + return this.remnants; + } + + public void generatePermutations() { + for (PositionedStack p : this.inputs) { + p.generatePermutations(); + } + } + + } + + @Override + public String getRecipeID() { + return "forestry.squeezer"; + } + + @Override + public String getRecipeName() { + return StatCollector.translateToLocal("tile.for.factory.5.name"); + } + + @Override + public String getGuiTexture() { + return "forestry:textures/gui/squeezersocket.png"; + } + + @Override + public void loadTransferRects() { + this.addTransferRect(98 - 16 - 6 - 4, 9 + 8 + 8 + 4, 15 + 16 + 6 + 4, 18); + } + + @Override + public void drawExtras(int recipeIndex) { + CachedRecipe recipe = arecipes.get(recipeIndex); + if (recipe instanceof CachedSqueezerRecipe) { + int processingTime = ((CachedSqueezerRecipe) recipe).processingTime; + this.drawProgressBar(70, 30, 176, 60, 43, 18, processingTime * 5, 0); + } + } + + @Override + public Class getGuiClass() { + return GuiSqueezer.class; + } + + @Override + public void loadAllRecipes() { + for (ISqueezerRecipe recipe : MachineSqueezer.RecipeManager.recipes) { + this.arecipes.add(new CachedSqueezerRecipe(recipe, true)); + } + } + + @Override + public void loadCraftingRecipes(ItemStack result) { + super.loadCraftingRecipes(result); + for (ISqueezerRecipe recipe : MachineSqueezer.RecipeManager.recipes) { + if (NEIServerUtils.areStacksSameTypeCrafting(recipe.getRemnants(), result)) { + this.arecipes.add(new CachedSqueezerRecipe(recipe, true)); + } + } + } + + @Override + public void loadCraftingRecipes(FluidStack result) { + for (ISqueezerRecipe recipe : MachineSqueezer.RecipeManager.recipes) { + if (NEIUtils.areFluidsSameType(recipe.getFluidOutput(), result)) { + this.arecipes.add(new CachedSqueezerRecipe(recipe, true)); + } + } + } + + @Override + public void loadUsageRecipes(ItemStack ingred) { + for (ISqueezerRecipe recipe : MachineSqueezer.RecipeManager.recipes) { + CachedSqueezerRecipe crecipe = new CachedSqueezerRecipe(recipe); + if (crecipe.inputs != null && crecipe.contains(crecipe.inputs, ingred)) { + crecipe.generatePermutations(); + crecipe.setIngredientPermutation(crecipe.inputs, ingred); + this.arecipes.add(crecipe); + } + } + } + +} diff --git a/src/main/java/forestry/factory/recipes/nei/NEIHandlerStill.java b/src/main/java/forestry/factory/recipes/nei/NEIHandlerStill.java new file mode 100644 index 000000000..7a20dfacd --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/NEIHandlerStill.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.awt.Point; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.util.StatCollector; + +import net.minecraftforge.fluids.FluidStack; + +import forestry.factory.gadgets.MachineStill; +import forestry.factory.gui.GuiStill; + +import codechicken.lib.gui.GuiDraw; +import codechicken.nei.PositionedStack; + +public class NEIHandlerStill extends RecipeHandlerBase { + + public class CachedStillRecipe extends CachedBaseRecipe { + + public List tanks = new ArrayList(); + + public CachedStillRecipe(MachineStill.Recipe recipe) { + if (recipe.input != null) { + this.tanks.add(new PositionedFluidTank(recipe.input, 10000, new Rectangle(30, 4, 16, 58), NEIHandlerStill.this.getGuiTexture(), new Point(176, 0))); + } + if (recipe.output != null) { + this.tanks.add(new PositionedFluidTank(recipe.output, 10000, new Rectangle(120, 4, 16, 58), NEIHandlerStill.this.getGuiTexture(), new Point(176, 0))); + } + } + + @Override + public PositionedStack getResult() { + return null; + } + + @Override + public List getFluidTanks() { + return this.tanks; + } + + } + + @Override + public String getRecipeID() { + return "forestry.still"; + } + + @Override + public String getRecipeName() { + return StatCollector.translateToLocal("tile.for.factory.6.name"); + } + + @Override + public String getGuiTexture() { + return "forestry:textures/gui/still.png"; + } + + @Override + public void loadTransferRects() { + this.addTransferRect(76, 27, 14, 12); + } + + @Override + public Class getGuiClass() { + return GuiStill.class; + } + + @Override + public void drawBackground(int recipe) { + this.changeToGuiTexture(); + GuiDraw.drawTexturedModalRect(25, 0, 30, 11, 116, 65); + } + + @Override + public void drawExtras(int recipe) { + this.drawProgressBar(79, 6, 176, 74, 4, 18, 80, 11); + GuiDraw.drawTexturedModalRect(77, 46, 176, 60, 14, 14); + } + + @Override + public void loadAllRecipes() { + for (MachineStill.Recipe recipe : MachineStill.RecipeManager.recipes) { + this.arecipes.add(new CachedStillRecipe(recipe)); + } + } + + @Override + public void loadCraftingRecipes(FluidStack result) { + for (MachineStill.Recipe recipe : MachineStill.RecipeManager.recipes) { + if (NEIUtils.areFluidsSameType(recipe.output, result)) { + this.arecipes.add(new CachedStillRecipe(recipe)); + } + } + } + + @Override + public void loadUsageRecipes(FluidStack ingred) { + for (MachineStill.Recipe recipe : MachineStill.RecipeManager.recipes) { + if (NEIUtils.areFluidsSameType(recipe.input, ingred)) { + this.arecipes.add(new CachedStillRecipe(recipe)); + } + } + } + +} diff --git a/src/main/java/forestry/factory/recipes/nei/NEIIntegrationConfig.java b/src/main/java/forestry/factory/recipes/nei/NEIIntegrationConfig.java new file mode 100644 index 000000000..9d2aaa1be --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/NEIIntegrationConfig.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import forestry.core.proxy.Proxies; + +import codechicken.nei.api.API; +import codechicken.nei.api.IConfigureNEI; + +public class NEIIntegrationConfig implements IConfigureNEI { + + @Override + public void loadConfig() { + Proxies.log.info("Loading: " + getName()); + + registerHandler(new NEIHandlerShapedCustom()); + registerHandler(new NEIHandlerShapelessCustom()); + registerHandler(new NEIHandlerBottler()); + registerHandler(new NEIHandlerCarpenter()); + registerHandler(new NEIHandlerCentrifuge()); + registerHandler(new NEIHandlerFabricator()); + registerHandler(new NEIHandlerFermenter()); + registerHandler(new NEIHandlerMoistener()); + registerHandler(new NEIHandlerSqueezer()); + registerHandler(new NEIHandlerStill()); + } + + protected static void registerHandler(IRecipeHandlerBase handler) { + handler.prepare(); + API.registerRecipeHandler(handler); + API.registerUsageHandler(handler); + } + + @Override + public String getName() { + return "Forestry NEI Integration"; + } + + @Override + public String getVersion() { + return "1.0.0"; + } + +} diff --git a/src/main/java/forestry/factory/recipes/nei/NEIUtils.java b/src/main/java/forestry/factory/recipes/nei/NEIUtils.java new file mode 100644 index 000000000..37e5a5c9a --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/NEIUtils.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.StatCollector; + +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidBlock; +import net.minecraftforge.fluids.IFluidContainerItem; + +import codechicken.nei.NEIServerUtils; +import codechicken.nei.PositionedStack; + +public class NEIUtils { + + public static String translate(String unlocalized) { + return StatCollector.translateToLocal("neiintegration." + unlocalized); + } + + public static List getItemVariations(ItemStack base) { + List variations = new ArrayList(); + base.getItem().getSubItems(base.getItem(), null, variations); + Iterator itr = variations.iterator(); + ItemStack stack; + while (itr.hasNext()) { + stack = itr.next(); + if (!base.isItemEqual(stack) || !stack.hasTagCompound()) { + itr.remove(); + } + } + if (variations.isEmpty()) { + return Collections.singletonList(base); + } + return variations; + } + + public static FluidStack getFluidStack(ItemStack stack) { + if (stack != null) { + FluidStack fluidStack = null; + if (stack.getItem() instanceof IFluidContainerItem) { + fluidStack = ((IFluidContainerItem) stack.getItem()).getFluid(stack); + } + if (fluidStack == null) { + fluidStack = FluidContainerRegistry.getFluidForFilledItem(stack); + } + if (fluidStack == null && Block.getBlockFromItem(stack.getItem()) instanceof IFluidBlock) { + Fluid fluid = ((IFluidBlock) Block.getBlockFromItem(stack.getItem())).getFluid(); + if (fluid != null) { + fluidStack = new FluidStack(fluid, 1000); + } + } + return fluidStack; + } + return null; + } + + public static boolean areFluidsSameType(FluidStack fluidStack1, FluidStack fluidStack2) { + if (fluidStack1 == null || fluidStack2 == null) { + return false; + } + return fluidStack1.getFluid() == fluidStack2.getFluid(); + } + + public static void setIngredientPermutationNBT(INBTMatchingCachedRecipe recipe, ItemStack ingredient) { + Iterable ingredients = recipe.getIngredients(); + for (PositionedStack stack : ingredients) { + for (int i = 0; i < stack.items.length; i++) { + if (NEIServerUtils.areStacksSameTypeCrafting(ingredient, stack.items[i])) { + stack.item = stack.items[i]; + stack.item.setItemDamage(ingredient.getItemDamage()); + + if (ingredient.hasTagCompound()) { + NBTTagCompound ingredientNbt = (NBTTagCompound) ingredient.getTagCompound().copy(); + stack.item.setTagCompound(ingredientNbt); + if (recipe.preservesNBT()) { + recipe.getResult().item.setTagCompound(ingredientNbt); + } + } + + stack.items = new ItemStack[]{stack.item}; + stack.setPermutationToRender(0); + break; + } + } + } + } + + public static void setResultPermutationNBT(INBTMatchingCachedRecipe recipe, ItemStack result) { + PositionedStack recipeResult = recipe.getResult(); + if (recipe.preservesNBT()) { + NBTTagCompound resultNbt = result.getTagCompound(); + recipeResult.item.setTagCompound((NBTTagCompound) resultNbt.copy()); + Iterable ingredients = recipe.getIngredients(); + for (PositionedStack stack : ingredients) { + if (stack.item.hasTagCompound()) { + stack.item.setTagCompound((NBTTagCompound) resultNbt.copy()); + } + + stack.items = new ItemStack[]{stack.item}; + stack.setPermutationToRender(0); + } + } + } + +} diff --git a/src/main/java/forestry/factory/recipes/nei/PositionedFluidTank.java b/src/main/java/forestry/factory/recipes/nei/PositionedFluidTank.java new file mode 100644 index 000000000..d8fafd417 --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/PositionedFluidTank.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.awt.Point; +import java.awt.Rectangle; +import java.util.List; + +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IIcon; + +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTank; + +import org.lwjgl.opengl.GL11; + +import codechicken.lib.gui.GuiDraw; +import codechicken.nei.recipe.GuiCraftingRecipe; +import codechicken.nei.recipe.GuiUsageRecipe; + +public class PositionedFluidTank { + + public FluidTank tank; + public Rectangle position; + public String overlayTexture; + public Point overlayTexturePos; + public boolean flowingTexture = false; + public boolean showAmount = true; + public boolean perTick = false; + + public PositionedFluidTank(FluidTank tank, Rectangle position, String overlayTexture, Point overlayTexturePos) { + this.position = position; + this.tank = tank; + this.overlayTexture = overlayTexture; + this.overlayTexturePos = overlayTexturePos; + } + + public PositionedFluidTank(FluidStack fluid, int capacity, Rectangle position, String overlayTexture, Point overlayTexturePos) { + this(new FluidTank(fluid != null ? fluid.copy() : null, capacity), position, overlayTexture, overlayTexturePos); + } + + public PositionedFluidTank(FluidStack fluid, int capacity, Rectangle position) { + this(fluid, capacity, position, null, null); + } + + public List handleTooltip(List currenttip) { + if (this.tank == null || this.tank.getFluid() == null || this.tank.getFluid().getFluid() == null || this.tank.getFluid().amount <= 0) { + return currenttip; + } + currenttip.add(this.tank.getFluid().getLocalizedName()); + if (this.showAmount) { + currenttip.add(EnumChatFormatting.GRAY.toString() + this.tank.getFluid().amount + (this.perTick ? " mB/t" : " mB")); + } + return currenttip; + } + + public boolean transfer(boolean usage) { + if (this.tank.getFluid() != null && this.tank.getFluid().amount > 0) { + if (usage) { + if (!GuiUsageRecipe.openRecipeGui("liquid", this.tank.getFluid())) { + return false; + } + } else { + if (!GuiCraftingRecipe.openRecipeGui("liquid", this.tank.getFluid())) { + return false; + } + } + return true; + } + return false; + } + + public void draw() { + if (this.tank == null || this.tank.getFluid() == null || this.tank.getFluid().getFluid() == null || this.tank.getFluid().amount <= 0) { + return; + } + final IIcon fluidIcon; + if (this.flowingTexture && this.tank.getFluid().getFluid().getFlowingIcon() != null) { + fluidIcon = this.tank.getFluid().getFluid().getFlowingIcon(); + } else if (this.tank.getFluid().getFluid().getStillIcon() != null) { + fluidIcon = this.tank.getFluid().getFluid().getStillIcon(); + } else { + return; + } + + GuiDraw.changeTexture(TextureMap.locationBlocksTexture); + int color = this.tank.getFluid().getFluid().getColor(this.tank.getFluid()); + GL11.glColor3ub((byte) (color >> 16 & 0xFF), (byte) (color >> 8 & 0xFF), (byte) (color & 0xFF)); + GL11.glDisable(GL11.GL_BLEND); + + int amount = Math.max(Math.min(this.position.height, this.tank.getFluid().amount * this.position.height / this.tank.getCapacity()), 1); + int posY = this.position.y + this.position.height - amount; + + for (int i = 0; i < this.position.width; i += 16) { + for (int j = 0; j < amount; j += 16) { + int drawWidth = Math.min(this.position.width - i, 16); + int drawHeight = Math.min(amount - j, 16); + + int drawX = this.position.x + i; + int drawY = posY + j; + + double minU = fluidIcon.getMinU(); + double maxU = fluidIcon.getMaxU(); + double minV = fluidIcon.getMinV(); + double maxV = fluidIcon.getMaxV(); + + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(drawX, drawY + drawHeight, 0, minU, minV + (maxV - minV) * drawHeight / 16F); + tessellator.addVertexWithUV(drawX + drawWidth, drawY + drawHeight, 0, minU + (maxU - minU) * drawWidth / 16F, minV + (maxV - minV) * drawHeight / 16F); + tessellator.addVertexWithUV(drawX + drawWidth, drawY, 0, minU + (maxU - minU) * drawWidth / 16F, minV); + tessellator.addVertexWithUV(drawX, drawY, 0, minU, minV); + tessellator.draw(); + } + } + + GL11.glEnable(GL11.GL_BLEND); + + if (this.overlayTexture != null && this.overlayTexturePos != null) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GuiDraw.changeTexture(this.overlayTexture); + GuiDraw.drawTexturedModalRect(this.position.x, this.position.y, this.overlayTexturePos.x, this.overlayTexturePos.y, this.position.width, this.position.height); + } + } +} diff --git a/src/main/java/forestry/factory/recipes/nei/PositionedStackAdv.java b/src/main/java/forestry/factory/recipes/nei/PositionedStackAdv.java new file mode 100644 index 000000000..d298c34bc --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/PositionedStackAdv.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.awt.Rectangle; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.util.EnumChatFormatting; + +import codechicken.nei.PositionedStack; +import codechicken.nei.recipe.GuiRecipe; + +public class PositionedStackAdv extends PositionedStack { + + private List tooltip = new ArrayList(); + + public PositionedStackAdv(Object object, int x, int y) { + super(object, x, y); + } + + public PositionedStackAdv(Object object, int x, int y, List tooltip) { + super(object, x, y); + this.addToTooltip(tooltip); + } + + public Rectangle getRect() { + return new Rectangle(this.relx - 1, this.rely - 1, 18, 18); + } + + public List handleTooltip(GuiRecipe guiRecipe, List currenttip) { + if (!this.tooltip.isEmpty()) { + for (String tip : this.tooltip) { + currenttip.add(tip); + } + } + return currenttip; + } + + public PositionedStackAdv addToTooltip(List lines) { + for (String tip : lines) { + this.tooltip.add(tip); + } + return this; + } + + public PositionedStackAdv addToTooltip(String line) { + this.tooltip.add(line); + return this; + } + + public PositionedStackAdv setChance(float chance) { + if (chance <= 0.0F) { + this.tooltip.add(EnumChatFormatting.GRAY + String.format(NEIUtils.translate("chance"), NEIUtils.translate("chance.never"))); + } else if (chance < 0.01F) { + this.tooltip.add(EnumChatFormatting.GRAY + String.format(NEIUtils.translate("chance"), NEIUtils.translate("chance.lessThan1"))); + } else if (chance != 1.0F) { + NumberFormat percentFormat = NumberFormat.getPercentInstance(); + percentFormat.setMaximumFractionDigits(2); + this.tooltip.add(EnumChatFormatting.GRAY + String.format(NEIUtils.translate("chance"), String.valueOf(percentFormat.format(chance)))); + } + return this; + } + +} diff --git a/src/main/java/forestry/factory/recipes/nei/RecipeHandlerBase.java b/src/main/java/forestry/factory/recipes/nei/RecipeHandlerBase.java new file mode 100644 index 000000000..90a3fff2b --- /dev/null +++ b/src/main/java/forestry/factory/recipes/nei/RecipeHandlerBase.java @@ -0,0 +1,236 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.factory.recipes.nei; + +import java.awt.Point; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.item.ItemStack; + +import net.minecraftforge.fluids.FluidStack; + +import org.lwjgl.opengl.GL11; + +import codechicken.lib.gui.GuiDraw; +import codechicken.nei.NEIClientConfig; +import codechicken.nei.PositionedStack; +import codechicken.nei.guihook.GuiContainerManager; +import codechicken.nei.recipe.GuiRecipe; +import codechicken.nei.recipe.TemplateRecipeHandler; + +public abstract class RecipeHandlerBase extends TemplateRecipeHandler implements IRecipeHandlerBase { + + @Override + public void prepare() { + } + + public abstract class CachedBaseRecipe extends CachedRecipe { + + public List getFluidTanks() { + List tanks = new ArrayList(); + PositionedFluidTank tank = this.getFluidTank(); + if (tank != null) { + tanks.add(tank); + } + return tanks; + } + + public PositionedFluidTank getFluidTank() { + return null; + } + + } + + public abstract String getRecipeID(); + + public String getRecipeSubName() { + return null; + } + + public void changeToGuiTexture() { + GuiDraw.changeTexture(this.getGuiTexture()); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + public void addTransferRect(int x, int y, int width, int height) { + this.transferRects.add(new RecipeTransferRect(new Rectangle(x, y, width, height), this.getRecipeID())); + } + + @Override + public void drawForeground(int recipe) { + super.drawForeground(recipe); + this.drawFluidTanks(recipe); + if (recipe % this.recipiesPerPage() == 0 && this.getRecipeSubName() != null) { + GuiDraw.drawStringC(this.getRecipeSubName(), 83, -2, 0x404040, false); + } + this.changeToGuiTexture(); + } + + @Override + public void loadCraftingRecipes(String outputId, Object... results) { + if (outputId.equals("liquid") && results[0] instanceof FluidStack && ((FluidStack) results[0]).getFluid() != null) { + this.loadCraftingRecipes((FluidStack) results[0]); + } else if (outputId.equals(this.getRecipeID())) { + this.loadAllRecipes(); + } else { + super.loadCraftingRecipes(outputId, results); + } + } + + public void loadAllRecipes() { + } + + @Override + public void loadCraftingRecipes(ItemStack result) { + FluidStack fluid = NEIUtils.getFluidStack(result); + if (fluid != null && fluid.getFluid() != null) { + this.loadCraftingRecipes(fluid); + } + } + + public void loadCraftingRecipes(FluidStack result) { + } + + @Override + public void loadUsageRecipes(String inputId, Object... ingredients) { + if (inputId.equals("liquid") && ingredients[0] instanceof FluidStack && ((FluidStack) ingredients[0]).getFluid() != null) { + this.loadUsageRecipes((FluidStack) ingredients[0]); + } else { + super.loadUsageRecipes(inputId, ingredients); + } + } + + @Override + public void loadUsageRecipes(ItemStack ingred) { + FluidStack fluid = NEIUtils.getFluidStack(ingred); + if (fluid != null && fluid.getFluid() != null) { + this.loadUsageRecipes(fluid); + } + } + + public void loadUsageRecipes(FluidStack ingredient) { + } + + @Override + public List handleTooltip(GuiRecipe guiRecipe, List currenttip, int recipe) { + super.handleTooltip(guiRecipe, currenttip, recipe); + CachedBaseRecipe crecipe = (CachedBaseRecipe) this.arecipes.get(recipe); + if (GuiContainerManager.shouldShowTooltip(guiRecipe)) { + Point mouse = GuiDraw.getMousePosition(); + Point offset = guiRecipe.getRecipePosition(recipe); + Point relMouse = new Point(mouse.x - (guiRecipe.width - 176) / 2 - offset.x, mouse.y - (guiRecipe.height - 166) / 2 - offset.y); + + currenttip = this.provideTooltip(guiRecipe, currenttip, crecipe, relMouse); + } + return currenttip; + } + + @Override + public List handleItemTooltip(GuiRecipe guiRecipe, ItemStack itemStack, List currenttip, int recipe) { + super.handleItemTooltip(guiRecipe, itemStack, currenttip, recipe); + CachedBaseRecipe crecipe = (CachedBaseRecipe) this.arecipes.get(recipe); + Point mouse = GuiDraw.getMousePosition(); + Point offset = guiRecipe.getRecipePosition(recipe); + Point relMouse = new Point(mouse.x - (guiRecipe.width - 176) / 2 - offset.x, mouse.y - (guiRecipe.height - 166) / 2 - offset.y); + + currenttip = this.provideItemTooltip(guiRecipe, itemStack, currenttip, crecipe, relMouse); + return currenttip; + } + + public List provideTooltip(GuiRecipe guiRecipe, List currenttip, CachedBaseRecipe crecipe, Point relMouse) { + if (crecipe.getFluidTanks() != null) { + for (PositionedFluidTank tank : crecipe.getFluidTanks()) { + if (tank.position.contains(relMouse)) { + tank.handleTooltip(currenttip); + } + } + } + return currenttip; + } + + public List provideItemTooltip(GuiRecipe guiRecipe, ItemStack itemStack, List currenttip, CachedBaseRecipe crecipe, Point relMouse) { + for (PositionedStack stack : crecipe.getIngredients()) { + if (stack instanceof PositionedStackAdv && ((PositionedStackAdv) stack).getRect().contains(relMouse)) { + currenttip = ((PositionedStackAdv) stack).handleTooltip(guiRecipe, currenttip); + } + } + for (PositionedStack stack : crecipe.getOtherStacks()) { + if (stack instanceof PositionedStackAdv && ((PositionedStackAdv) stack).getRect().contains(relMouse)) { + currenttip = ((PositionedStackAdv) stack).handleTooltip(guiRecipe, currenttip); + } + } + PositionedStack stack = crecipe.getResult(); + if (stack instanceof PositionedStackAdv && ((PositionedStackAdv) stack).getRect().contains(relMouse)) { + currenttip = ((PositionedStackAdv) stack).handleTooltip(guiRecipe, currenttip); + } + return currenttip; + } + + @Override + public boolean keyTyped(GuiRecipe gui, char keyChar, int keyCode, int recipe) { + if (keyCode == NEIClientConfig.getKeyBinding("gui.recipe")) { + if (this.transferFluidTank(gui, recipe, false)) { + return true; + } + } else if (keyCode == NEIClientConfig.getKeyBinding("gui.usage")) { + if (this.transferFluidTank(gui, recipe, true)) { + return true; + } + } + return super.keyTyped(gui, keyChar, keyCode, recipe); + } + + @Override + public boolean mouseClicked(GuiRecipe gui, int button, int recipe) { + if (button == 0) { + if (this.transferFluidTank(gui, recipe, false)) { + return true; + } + } else if (button == 1) { + if (this.transferFluidTank(gui, recipe, true)) { + return true; + } + } + return super.mouseClicked(gui, button, recipe); + } + + protected boolean transferFluidTank(GuiRecipe guiRecipe, int recipe, boolean usage) { + CachedBaseRecipe crecipe = (CachedBaseRecipe) this.arecipes.get(recipe); + Point mousepos = GuiDraw.getMousePosition(); + Point offset = guiRecipe.getRecipePosition(recipe); + Point relMouse = new Point(mousepos.x - (guiRecipe.width - 176) / 2 - offset.x, mousepos.y - (guiRecipe.height - 166) / 2 - offset.y); + + if (crecipe.getFluidTanks() != null) { + for (PositionedFluidTank tank : crecipe.getFluidTanks()) { + if (tank.position.contains(relMouse)) { + return tank.transfer(usage); + } + } + } + + return false; + } + + public void drawFluidTanks(int recipe) { + CachedRecipe cachedRecipe = this.arecipes.get(recipe); + if (cachedRecipe instanceof CachedBaseRecipe) { + CachedBaseRecipe crecipe = (CachedBaseRecipe) cachedRecipe; + if (crecipe.getFluidTanks() != null) { + for (PositionedFluidTank fluidTank : crecipe.getFluidTanks()) { + fluidTank.draw(); + } + } + } + } + +} diff --git a/src/main/java/forestry/plugins/PluginArboriculture.java b/src/main/java/forestry/plugins/PluginArboriculture.java index af1a21d17..511c5442e 100644 --- a/src/main/java/forestry/plugins/PluginArboriculture.java +++ b/src/main/java/forestry/plugins/PluginArboriculture.java @@ -273,8 +273,8 @@ public class PluginArboriculture extends ForestryPlugin { Proxies.common.addSmelting(ForestryBlock.logs.getWildcard(), new ItemStack(Items.coal, 1, 1), 0.15F); - ShapelessRecipeCustom.buildRecipe(ForestryBlock.planks.getItemStack(4), ForestryBlock.logs.getItemStack()).setPreserveNBT(); - ShapelessRecipeCustom.buildRecipe(ForestryBlock.planksFireproof.getItemStack(4), ForestryBlock.logsFireproof.getItemStack()).setPreserveNBT(); + ShapelessRecipeCustom.buildRecipe(ForestryBlock.planks.getItemStack(4), ForestryBlock.logs.getWildcard()).setPreserveNBT(); + ShapelessRecipeCustom.buildRecipe(ForestryBlock.planksFireproof.getItemStack(4), ForestryBlock.logsFireproof.getWildcard()).setPreserveNBT(); // Fabricator recipes if (PluginManager.Module.FACTORY.isEnabled() && PluginManager.Module.APICULTURE.isEnabled()) { @@ -285,7 +285,7 @@ public class PluginArboriculture extends ForestryPlugin { "#X#", " # ", '#', ForestryItem.refractoryWax, - 'X', ForestryBlock.logs.getItemStack()}).setPreserveNBT()); + 'X', ForestryBlock.logs.getWildcard()}).setPreserveNBT()); // Fireproof plank recipe RecipeManagers.fabricatorManager.addRecipe(new FabricatorRecipe(null, Fluids.GLASS.getFluid(500), ForestryBlock.planksFireproof.getItemStack(5), new Object[]{ @@ -293,14 +293,14 @@ public class PluginArboriculture extends ForestryPlugin { "#X#", "X#X", '#', ForestryItem.refractoryWax, - 'X', ForestryBlock.planks.getItemStack()}).setPreserveNBT()); + 'X', ForestryBlock.planks.getWildcard()}).setPreserveNBT()); } - ShapedRecipeCustom.buildPriorityRecipe(ForestryBlock.slabs.getItemStack(6), "###", '#', ForestryBlock.planks).setPreserveNBT(); - ShapedRecipeCustom.buildPriorityRecipe(ForestryBlock.slabsFireproof.getItemStack(6), "###", '#', ForestryBlock.planksFireproof).setPreserveNBT(); + ShapedRecipeCustom.buildPriorityRecipe(ForestryBlock.slabs.getItemStack(6), "###", '#', ForestryBlock.planks.getWildcard()).setPreserveNBT(); + ShapedRecipeCustom.buildPriorityRecipe(ForestryBlock.slabsFireproof.getItemStack(6), "###", '#', ForestryBlock.planksFireproof.getWildcard()).setPreserveNBT(); - ShapedRecipeCustom.buildRecipe(ForestryBlock.fences.getItemStack(3), "#X#", "#X#", '#', ForestryBlock.planks.getItemStack(1), 'X', "stickWood").setPreserveNBT(); - ShapedRecipeCustom.buildRecipe(ForestryBlock.fencesFireproof.getItemStack(3), "#X#", "#X#", '#', ForestryBlock.planksFireproof.getItemStack(1), 'X', "stickWood").setPreserveNBT(); + ShapedRecipeCustom.buildRecipe(ForestryBlock.fences.getItemStack(3), "#X#", "#X#", '#', ForestryBlock.planks.getWildcard(), 'X', "stickWood").setPreserveNBT(); + ShapedRecipeCustom.buildRecipe(ForestryBlock.fencesFireproof.getItemStack(3), "#X#", "#X#", '#', ForestryBlock.planksFireproof.getWildcard(), 'X', "stickWood").setPreserveNBT(); if (PluginManager.Module.FACTORY.isEnabled()) { // Treealyzer @@ -330,13 +330,13 @@ public class PluginArboriculture extends ForestryPlugin { "# ", "## ", "###", - '#', ForestryBlock.planks.getItemStack()).setPreserveNBT(); + '#', ForestryBlock.planks.getWildcard()).setPreserveNBT(); ShapedRecipeCustom.buildPriorityRecipe(ForestryBlock.stairsFireproof.getItemStack(4), "# ", "## ", "###", - '#', ForestryBlock.planksFireproof.getItemStack()).setPreserveNBT(); + '#', ForestryBlock.planksFireproof.getWildcard()).setPreserveNBT(); // Grafter Proxies.common.addRecipe(ForestryItem.grafter.getItemStack(), diff --git a/src/main/java/forestry/plugins/PluginFactory.java b/src/main/java/forestry/plugins/PluginFactory.java index bbb00d0fd..d2e176d1d 100644 --- a/src/main/java/forestry/plugins/PluginFactory.java +++ b/src/main/java/forestry/plugins/PluginFactory.java @@ -54,7 +54,7 @@ import forestry.factory.gadgets.MachineStill; import forestry.factory.gadgets.MillRainmaker; import forestry.factory.gadgets.TileWorktable; import forestry.factory.network.PacketHandlerFactory; -import forestry.factory.recipes.CraftGuideIntegration; +import forestry.factory.recipes.craftguide.CraftGuideIntegration; import forestry.factory.triggers.FactoryTriggers;