diff --git a/api/buildcraft/api/recipes/IIntegrationRecipe.java b/api/buildcraft/api/recipes/IIntegrationRecipe.java new file mode 100644 index 00000000..f3e81193 --- /dev/null +++ b/api/buildcraft/api/recipes/IIntegrationRecipe.java @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team + * http://www.mod-buildcraft.com + * + * BuildCraft is distributed under the terms of the Minecraft Mod Public + * License 1.0, or MMPL. Please check the contents of the license located in + * http://www.mod-buildcraft.com/MMPL-1.0.txt + */ +package buildcraft.api.recipes; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; + +public interface IIntegrationRecipe { + public static class IntegrationResult { + public double energyCost; + public ItemStack output; + public ItemStack[] usedComponents; + + public static IntegrationResult create(double energyCost, ItemStack output, ItemStack... usedComponents) { + IntegrationResult result = new IntegrationResult(); + result.energyCost = energyCost; + result.output = output; + result.usedComponents = usedComponents; + return result; + } + + public static boolean enoughComponents(ItemStack[] components, ItemStack... needs) { + for (ItemStack need : needs) { + int found = 0; + for (ItemStack component : components) { + if (isMatchingItem(need, component)) { + found += component.stackSize; + } + } + if (found < need.stackSize) { + return false; + } + } + return true; + } + + public static boolean isMatchingItem(ItemStack a, ItemStack b) { + if (a == null || b == null) { + return false; + } + if (a.getItem() != b.getItem()) { + return false; + } + if (a.getHasSubtypes() && !isWildcard(a) && !isWildcard(b) && a.getItemDamage() != b.getItemDamage()) { + return false; + } + return a.stackTagCompound == null ? b.stackTagCompound == null : a.stackTagCompound.equals(b.stackTagCompound); + } + + private static boolean isWildcard(ItemStack stack) { + final int damage = stack.getItemDamage(); + return damage == -1 || damage == OreDictionary.WILDCARD_VALUE; + } + } + + boolean isValidInputA(ItemStack inputA); + + boolean isValidInputB(ItemStack inputB); + + IntegrationResult integrate(ItemStack inputA, ItemStack inputB, ItemStack[] components); +} \ No newline at end of file diff --git a/api/buildcraft/api/recipes/IIntegrationRecipeManager.java b/api/buildcraft/api/recipes/IIntegrationRecipeManager.java index 842b4436..f18ae77b 100644 --- a/api/buildcraft/api/recipes/IIntegrationRecipeManager.java +++ b/api/buildcraft/api/recipes/IIntegrationRecipeManager.java @@ -10,35 +10,14 @@ package buildcraft.api.recipes; import java.util.List; -import net.minecraft.item.ItemStack; - /** * The Integration Table's primary purpose is to modify an input item's NBT * data. As such its not a "traditional" type of recipe. Rather than predefined * inputs and outputs, it takes an input and transforms it. */ public interface IIntegrationRecipeManager { - - public interface IIntegrationRecipe { - - double getEnergyCost(); - - boolean isValidInputA(ItemStack inputA); - - boolean isValidInputB(ItemStack inputB); - - ItemStack getOutputForInputs(ItemStack inputA, ItemStack inputB, ItemStack[] components); - - ItemStack[] getComponents(); - - ItemStack[] getExampleInputsA(); - - ItemStack[] getExampleInputsB(); - } - /** * Add an Integration Table recipe. - * */ void addRecipe(IIntegrationRecipe recipe); diff --git a/common/buildcraft/BuildCraftSilicon.java b/common/buildcraft/BuildCraftSilicon.java index cf25f20d..d0d014d8 100644 --- a/common/buildcraft/BuildCraftSilicon.java +++ b/common/buildcraft/BuildCraftSilicon.java @@ -9,7 +9,6 @@ package buildcraft; import java.util.ArrayList; -import java.util.EnumSet; import java.util.List; import net.minecraft.init.Blocks; @@ -213,13 +212,8 @@ public class BuildCraftSilicon extends BuildCraftMod { BuildcraftRecipes.assemblyTable.addRecipe(new BoardRecipe()); BuildcraftRecipes.integrationTable.addRecipe(new RobotIntegrationRecipe()); - // REVERSAL RECIPES - EnumSet materials = EnumSet.allOf(GateMaterial.class); - materials.remove(GateMaterial.REDSTONE); - for (GateMaterial material : materials) { - BuildcraftRecipes.integrationTable.addRecipe(new GateLogicSwapRecipe(material, GateLogic.AND, GateLogic.OR)); - BuildcraftRecipes.integrationTable.addRecipe(new GateLogicSwapRecipe(material, GateLogic.OR, GateLogic.AND)); - } + // REVERSAL RECIPE + BuildcraftRecipes.integrationTable.addRecipe(new GateLogicSwapRecipe()); // EXPANSIONS BuildcraftRecipes.integrationTable.addRecipe(new GateExpansionRecipe(GateExpansionPulsar.INSTANCE, Chipset.PULSATING.getStack())); diff --git a/common/buildcraft/core/recipes/IntegrationRecipeManager.java b/common/buildcraft/core/recipes/IntegrationRecipeManager.java index 5f4e5e94..6ad4c439 100644 --- a/common/buildcraft/core/recipes/IntegrationRecipeManager.java +++ b/common/buildcraft/core/recipes/IntegrationRecipeManager.java @@ -11,10 +11,10 @@ package buildcraft.core.recipes; import java.util.LinkedList; import java.util.List; +import buildcraft.api.recipes.IIntegrationRecipe; import buildcraft.api.recipes.IIntegrationRecipeManager; public class IntegrationRecipeManager implements IIntegrationRecipeManager { - public static final IntegrationRecipeManager INSTANCE = new IntegrationRecipeManager(); private List integrationRecipes = new LinkedList(); @@ -24,7 +24,7 @@ public class IntegrationRecipeManager implements IIntegrationRecipeManager { } @Override - public List getRecipes() { + public List getRecipes() { return integrationRecipes; } } diff --git a/common/buildcraft/core/robots/RobotIntegrationRecipe.java b/common/buildcraft/core/robots/RobotIntegrationRecipe.java index 160559fb..f7cc26c7 100755 --- a/common/buildcraft/core/robots/RobotIntegrationRecipe.java +++ b/common/buildcraft/core/robots/RobotIntegrationRecipe.java @@ -11,19 +11,12 @@ package buildcraft.core.robots; import net.minecraft.item.ItemStack; import buildcraft.BuildCraftSilicon; -import buildcraft.api.recipes.IIntegrationRecipeManager.IIntegrationRecipe; +import buildcraft.api.recipes.IIntegrationRecipe; import buildcraft.core.ItemRobot; import buildcraft.core.utils.NBTUtils; import buildcraft.silicon.ItemRedstoneBoard; public class RobotIntegrationRecipe implements IIntegrationRecipe { - - @Override - public double getEnergyCost() { - // return 10000; - return 100; - } - @Override public boolean isValidInputA(ItemStack inputA) { return inputA != null && inputA.getItem() instanceof ItemRobot; @@ -35,27 +28,11 @@ public class RobotIntegrationRecipe implements IIntegrationRecipe { } @Override - public ItemStack getOutputForInputs(ItemStack inputA, ItemStack inputB, ItemStack[] components) { + public IntegrationResult integrate(ItemStack inputA, ItemStack inputB, ItemStack[] components) { ItemStack robot = new ItemStack(BuildCraftSilicon.robotItem); NBTUtils.getItemData(robot).setTag("board", NBTUtils.getItemData(inputB)); - return robot; + return IntegrationResult.create(10000, robot); } - - @Override - public ItemStack[] getComponents() { - return new ItemStack[0]; - } - - @Override - public ItemStack[] getExampleInputsA() { - return null; - } - - @Override - public ItemStack[] getExampleInputsB() { - return null; - } - } diff --git a/common/buildcraft/silicon/TileIntegrationTable.java b/common/buildcraft/silicon/TileIntegrationTable.java index a8885ae3..77135220 100644 --- a/common/buildcraft/silicon/TileIntegrationTable.java +++ b/common/buildcraft/silicon/TileIntegrationTable.java @@ -15,7 +15,7 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.common.util.ForgeDirection; import buildcraft.api.recipes.BuildcraftRecipes; -import buildcraft.api.recipes.IIntegrationRecipeManager.IIntegrationRecipe; +import buildcraft.api.recipes.IIntegrationRecipe; import buildcraft.core.inventory.ITransactor; import buildcraft.core.inventory.InventoryMapper; import buildcraft.core.inventory.SimpleInventory; @@ -36,7 +36,7 @@ public class TileIntegrationTable extends TileLaserTableBase implements ISidedIn private int tick = 0; private SimpleInventory invRecipeOutput = new SimpleInventory(1, "integrationOutput", 64); private InventoryMapper invOutput = new InventoryMapper(inv, SLOT_OUTPUT, 1, false); - private IIntegrationRecipe currentRecipe; + private IIntegrationRecipe.IntegrationResult integrationResult; private boolean canCraft = false; public IInventory getRecipeOutput() { @@ -51,35 +51,6 @@ public class TileIntegrationTable extends TileLaserTableBase implements ISidedIn return components; } - private boolean containsComponents(IIntegrationRecipe recipe) { - if (recipe == null) { - return false; - } - - ItemStack[] components = recipe.getComponents(); - if (components == null || components.length == 0) { - return true; - } - - for (ItemStack stack : components) { - int found = 0; - for (int i = SLOT_OUTPUT + 1; i < 12; i++) { - ItemStack stack1 = inv.getStackInSlot(i); - - if (stack1 != null) { - if (StackHelper.isMatchingItem(stack, stack1, true, false)) { - found += stack1.stackSize; - } - } - } - if (found == 0) { - return false; - } - } - - return true; - } - @Override public void updateEntity() { super.updateEntity(); @@ -95,57 +66,58 @@ public class TileIntegrationTable extends TileLaserTableBase implements ISidedIn canCraft = false; - currentRecipe = findMatchingRecipe(); - - if (currentRecipe == null) { + ItemStack inputA = inv.getStackInSlot(SLOT_INPUT_A); + ItemStack inputB = inv.getStackInSlot(SLOT_INPUT_B); + ItemStack[] components = getComponents(); + integrationResult = integrate(inputA, inputB, components); + if (integrationResult == null || integrationResult.output == null) { setEnergy(0); return; } - ItemStack inputA = inv.getStackInSlot(SLOT_INPUT_A); - ItemStack inputB = inv.getStackInSlot(SLOT_INPUT_B); - ItemStack[] components = getComponents(); - ItemStack output = currentRecipe.getOutputForInputs(inputA, inputB, components); - invRecipeOutput.setInventorySlotContents(0, output); + invRecipeOutput.setInventorySlotContents(0, integrationResult.output); - if (!isRoomForOutput(output)) { + if (!isRoomForOutput(integrationResult.output)) { setEnergy(0); return; } canCraft = true; - if (getEnergy() >= currentRecipe.getEnergyCost() && lastMode != ActionMachineControl.Mode.Off) { + if (getEnergy() >= integrationResult.energyCost && lastMode != ActionMachineControl.Mode.Off) { setEnergy(0); inv.decrStackSize(SLOT_INPUT_A, 1); inv.decrStackSize(SLOT_INPUT_B, 1); // For each required component, loop through the component inventory - for (ItemStack stack : currentRecipe.getComponents()) { + for (ItemStack stack : integrationResult.usedComponents) { + int decreased = 0; for (int i = SLOT_OUTPUT + 1; i < 12; i++) { ItemStack stack1 = inv.getStackInSlot(i); if (stack1 != null) { if (StackHelper.isMatchingItem(stack, stack1, true, false)) { - inv.decrStackSize(i, 1); - break; + decreased += stack1.stackSize; + inv.decrStackSize(i, stack.stackSize - decreased); } } + if (decreased >= stack.stackSize) { + break; + } } } ITransactor trans = Transactor.getTransactorFor(invOutput); - trans.add(output, ForgeDirection.UP, true); + trans.add(integrationResult.output, ForgeDirection.UP, true); } } - private IIntegrationRecipe findMatchingRecipe() { - ItemStack inputA = inv.getStackInSlot(SLOT_INPUT_A); - ItemStack inputB = inv.getStackInSlot(SLOT_INPUT_B); - + private IIntegrationRecipe.IntegrationResult integrate(ItemStack inputA, ItemStack inputB, ItemStack[] components) { + IIntegrationRecipe.IntegrationResult result; for (IIntegrationRecipe recipe : BuildcraftRecipes.integrationTable.getRecipes()) { - if (recipe.isValidInputA(inputA) && recipe.isValidInputB(inputB) && containsComponents(recipe)) { - return recipe; + if (recipe.isValidInputA(inputA) && recipe.isValidInputB(inputB) && + (result = recipe.integrate(inputA, inputB, components)) != null) { + return result; } } return null; @@ -164,8 +136,8 @@ public class TileIntegrationTable extends TileLaserTableBase implements ISidedIn @Override public double getRequiredEnergy() { - if (currentRecipe != null) { - return currentRecipe.getEnergyCost(); + if (integrationResult != null) { + return integrationResult.energyCost; } return 0.0; } @@ -238,6 +210,7 @@ public class TileIntegrationTable extends TileLaserTableBase implements ISidedIn @Override public boolean isActive() { - return currentRecipe != null && super.isActive(); + return integrationResult != null && super.isActive(); } + } diff --git a/common/buildcraft/silicon/recipes/AdvancedFacadeRecipe.java b/common/buildcraft/silicon/recipes/AdvancedFacadeRecipe.java index 5376def0..b946d96d 100644 --- a/common/buildcraft/silicon/recipes/AdvancedFacadeRecipe.java +++ b/common/buildcraft/silicon/recipes/AdvancedFacadeRecipe.java @@ -14,18 +14,14 @@ import net.minecraftforge.oredict.OreDictionary; import buildcraft.BuildCraftTransport; import buildcraft.api.core.JavaTools; -import buildcraft.api.recipes.IIntegrationRecipeManager; +import buildcraft.api.recipes.IIntegrationRecipe; import buildcraft.api.transport.PipeWire; import buildcraft.silicon.ItemRedstoneChipset; import buildcraft.transport.ItemFacade; import buildcraft.transport.ItemPipeWire; -public class AdvancedFacadeRecipe implements IIntegrationRecipeManager.IIntegrationRecipe { - - @Override - public double getEnergyCost() { - return 2500; - } +public class AdvancedFacadeRecipe implements IIntegrationRecipe { + private final ItemStack[] requiredComponents = new ItemStack[] {new ItemStack(BuildCraftTransport.pipeWire, 1, OreDictionary.WILDCARD_VALUE), ItemRedstoneChipset.Chipset.RED.getStack()}; @Override public boolean isValidInputA(ItemStack inputA) { @@ -39,12 +35,8 @@ public class AdvancedFacadeRecipe implements IIntegrationRecipeManager.IIntegrat } @Override - public ItemStack getOutputForInputs(ItemStack inputA, ItemStack inputB, ItemStack[] components) { - if (!isValidInputA(inputA)) { - return null; - } - - if (!isValidInputB(inputB)) { + public IntegrationResult integrate(ItemStack inputA, ItemStack inputB, ItemStack[] components) { + if (!IntegrationResult.enoughComponents(components, requiredComponents)) { return null; } @@ -57,6 +49,7 @@ public class AdvancedFacadeRecipe implements IIntegrationRecipeManager.IIntegrat } } + if (wire != null) { ItemFacade.FacadeState[] states = ItemFacade.getFacadeStates(inputA); ItemFacade.FacadeState additionalState; @@ -71,30 +64,13 @@ public class AdvancedFacadeRecipe implements IIntegrationRecipeManager.IIntegrat for (int i = 0; i < states.length; i++) { if (states[i].wire == wire) { states[i] = additionalState; - return ItemFacade.getFacade(states); + return IntegrationResult.create(2000, ItemFacade.getFacade(states), requiredComponents); } } // otherwise concat all states into one facade - return ItemFacade.getFacade(JavaTools.concat(states, new ItemFacade.FacadeState[] {additionalState})); + return IntegrationResult.create(5000, ItemFacade.getFacade(JavaTools.concat(states, new ItemFacade.FacadeState[] {additionalState})), requiredComponents); } else { return null; } } - - @Override - public ItemStack[] getComponents() { - // Any pipe wire and redstone chipset - return new ItemStack[] {new ItemStack(BuildCraftTransport.pipeWire, 1, OreDictionary.WILDCARD_VALUE), ItemRedstoneChipset.Chipset.RED.getStack()}; - } - - @Override - public ItemStack[] getExampleInputsA() { - return new ItemStack[0]; - } - - @Override - public ItemStack[] getExampleInputsB() { - return new ItemStack[0]; - } - } diff --git a/common/buildcraft/silicon/recipes/GateExpansionRecipe.java b/common/buildcraft/silicon/recipes/GateExpansionRecipe.java index 90f3628b..ca6bee99 100644 --- a/common/buildcraft/silicon/recipes/GateExpansionRecipe.java +++ b/common/buildcraft/silicon/recipes/GateExpansionRecipe.java @@ -10,7 +10,7 @@ package buildcraft.silicon.recipes; import net.minecraft.item.ItemStack; import buildcraft.api.gates.IGateExpansion; -import buildcraft.api.recipes.IIntegrationRecipeManager.IIntegrationRecipe; +import buildcraft.api.recipes.IIntegrationRecipe; import buildcraft.core.inventory.StackHelper; import buildcraft.transport.gates.ItemGate; @@ -18,19 +18,10 @@ public class GateExpansionRecipe implements IIntegrationRecipe { private final IGateExpansion expansion; private final ItemStack chipset; - private final ItemStack[] exampleA; - private final ItemStack[] exampleB; public GateExpansionRecipe(IGateExpansion expansion, ItemStack chipset) { this.expansion = expansion; this.chipset = chipset.copy(); - exampleA = ItemGate.getGateVarients(); - exampleB = new ItemStack[]{chipset}; - } - - @Override - public double getEnergyCost() { - return 10000; } @Override @@ -50,31 +41,10 @@ public class GateExpansionRecipe implements IIntegrationRecipe { } @Override - public ItemStack getOutputForInputs(ItemStack inputA, ItemStack inputB, ItemStack[] components) { - if (!isValidInputA(inputA)) { - return null; - } - if (!isValidInputB(inputB)) { - return null; - } + public IntegrationResult integrate(ItemStack inputA, ItemStack inputB, ItemStack[] components) { ItemStack output = inputA.copy(); output.stackSize = 1; ItemGate.addGateExpansion(output, expansion); - return output; - } - - @Override - public ItemStack[] getComponents() { - return new ItemStack[0]; - } - - @Override - public ItemStack[] getExampleInputsA() { - return exampleA; - } - - @Override - public ItemStack[] getExampleInputsB() { - return exampleB; + return IntegrationResult.create(10000, output); } } diff --git a/common/buildcraft/silicon/recipes/GateLogicSwapRecipe.java b/common/buildcraft/silicon/recipes/GateLogicSwapRecipe.java index 5dcee783..69f04cae 100644 --- a/common/buildcraft/silicon/recipes/GateLogicSwapRecipe.java +++ b/common/buildcraft/silicon/recipes/GateLogicSwapRecipe.java @@ -9,7 +9,8 @@ package buildcraft.silicon.recipes; import net.minecraft.item.ItemStack; -import buildcraft.api.recipes.IIntegrationRecipeManager.IIntegrationRecipe; + +import buildcraft.api.recipes.IIntegrationRecipe; import buildcraft.core.inventory.StackHelper; import buildcraft.silicon.ItemRedstoneChipset; import buildcraft.transport.gates.GateDefinition.GateLogic; @@ -17,75 +18,21 @@ import buildcraft.transport.gates.GateDefinition.GateMaterial; import buildcraft.transport.gates.ItemGate; public class GateLogicSwapRecipe implements IIntegrationRecipe { - - private final GateMaterial material; - private final GateLogic logicIn, logicOut; - private final ItemStack chipset; - private final ItemStack[] exampleA; - private final ItemStack[] exampleB; - - public GateLogicSwapRecipe(GateMaterial material, GateLogic logicIn, GateLogic logicOut) { - this.material = material; - this.logicIn = logicIn; - this.logicOut = logicOut; - this.chipset = ItemRedstoneChipset.Chipset.RED.getStack(); - exampleA = new ItemStack[]{ItemGate.makeGateItem(material, logicIn)}; - exampleB = new ItemStack[]{chipset}; - } - - @Override - public double getEnergyCost() { - return 2000; - } - @Override public boolean isValidInputA(ItemStack inputA) { - if (inputA == null) { - return false; - } - if (!(inputA.getItem() instanceof ItemGate)) { - return false; - } - if (ItemGate.getMaterial(inputA) != material) { - return false; - } - if (ItemGate.getLogic(inputA) != logicIn) { - return false; - } - return true; + return inputA != null && inputA.getItem() instanceof ItemGate && ItemGate.getMaterial(inputA) != GateMaterial.REDSTONE; } @Override public boolean isValidInputB(ItemStack inputB) { - return StackHelper.isMatchingItem(inputB, chipset); + return StackHelper.isMatchingItem(inputB, ItemRedstoneChipset.Chipset.RED.getStack()); } @Override - public ItemStack getOutputForInputs(ItemStack inputA, ItemStack inputB, ItemStack[] components) { - if (!isValidInputA(inputA)) { - return null; - } - if (!isValidInputB(inputB)) { - return null; - } + public IntegrationResult integrate(ItemStack inputA, ItemStack inputB, ItemStack[] components) { ItemStack output = inputA.copy(); output.stackSize = 1; - ItemGate.setLogic(output, logicOut); - return output; - } - - @Override - public ItemStack[] getComponents() { - return new ItemStack[0]; - } - - @Override - public ItemStack[] getExampleInputsA() { - return exampleA; - } - - @Override - public ItemStack[] getExampleInputsB() { - return exampleB; + ItemGate.setLogic(output, ItemGate.getLogic(output) == GateLogic.AND ? GateLogic.OR : GateLogic.AND); + return IntegrationResult.create(2000, output); } }