Merge branch 'integration-table-advanced-recipe' of https://github.com/Prototik/BuildCraft into Prototik-integration-table-advanced-recipe

This commit is contained in:
SpaceToad 2014-06-01 15:17:22 +02:00
commit fbf2cef772
9 changed files with 119 additions and 236 deletions

View file

@ -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);
}

View file

@ -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);

View file

@ -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<GateMaterial> 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()));

View file

@ -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<IIntegrationRecipe> integrationRecipes = new LinkedList<IIntegrationRecipe>();
@ -24,7 +24,7 @@ public class IntegrationRecipeManager implements IIntegrationRecipeManager {
}
@Override
public List<IIntegrationRecipe> getRecipes() {
public List<? extends IIntegrationRecipe> getRecipes() {
return integrationRecipes;
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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];
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}