Initial refactoring of recipe mechanics.

Assembly table should be ok, integration table and refinery still to go.
For #1851
This commit is contained in:
SpaceToad 2014-06-02 16:29:13 +02:00
parent fbf2cef772
commit cfb9095139
32 changed files with 890 additions and 674 deletions

View file

@ -8,12 +8,12 @@
*/
package buildcraft.api.recipes;
public final class BuildcraftRecipes {
public final class BuildcraftRecipeRegistry {
public static IAssemblyRecipeManager assemblyTable;
public static IIntegrationRecipeManager integrationTable;
public static IRefineryRecipeManager refinery;
private BuildcraftRecipes() {
private BuildcraftRecipeRegistry() {
}
}

View file

@ -0,0 +1,25 @@
/**
* 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 java.util.ArrayList;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
public class CraftingResult {
public Object crafted = null;
public ArrayList<ItemStack> usedItems = new ArrayList<ItemStack>();
public ArrayList<FluidStack> usedFluids = new ArrayList<FluidStack>();
public double energyCost = 0;
public IFlexibleRecipe recipe;
}

View file

@ -8,7 +8,7 @@
*/
package buildcraft.api.recipes;
import java.util.List;
import java.util.Collection;
import net.minecraft.item.ItemStack;
@ -25,9 +25,9 @@ public interface IAssemblyRecipeManager {
* @param output
* resulting ItemStack
*/
void addRecipe(double energyCost, ItemStack output, Object... input);
void addRecipe(String id, double energyCost, ItemStack output, Object... input);
void addRecipe(IAssemblyRecipe recipe);
void addRecipe(IFlexibleRecipe recipe);
List<? extends IAssemblyRecipe> getRecipes();
Collection<IFlexibleRecipe> getRecipes();
}

View file

@ -0,0 +1,25 @@
/**
* 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.inventory.IInventory;
import net.minecraftforge.fluids.IFluidHandler;
public interface IFlexibleRecipe {
boolean canBeCrafted(IInventory items, IFluidHandler fluids);
CraftingResult craftPreview(IInventory items, IFluidHandler fluids);
CraftingResult craft(IInventory items, IFluidHandler fluids);
String getId();
}

View file

@ -1,67 +0,0 @@
/**
* 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

@ -8,20 +8,12 @@
*/
package buildcraft.api.recipes;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
public interface IAssemblyRecipe {
public interface IIntegrationRecipeFactory extends IFlexibleRecipe {
ItemStack getOutput();
boolean isValidInputA(ItemStack inputA);
ItemStack makeOutput();
boolean isValidInputB(ItemStack inputB);
Object[] getInputs();
double getEnergyCost();
boolean canBeDone(IInventory inv);
void useItems(IInventory inv);
}

View file

@ -19,7 +19,7 @@ public interface IIntegrationRecipeManager {
/**
* Add an Integration Table recipe.
*/
void addRecipe(IIntegrationRecipe recipe);
void addRecipe(IIntegrationRecipeFactory recipe);
List<? extends IIntegrationRecipe> getRecipes();
List<? extends IIntegrationRecipeFactory> getRecipes();
}

View file

@ -61,7 +61,7 @@ import buildcraft.api.core.BuildCraftAPI;
import buildcraft.api.core.IIconProvider;
import buildcraft.api.core.JavaTools;
import buildcraft.api.gates.ActionManager;
import buildcraft.api.recipes.BuildcraftRecipes;
import buildcraft.api.recipes.BuildcraftRecipeRegistry;
import buildcraft.builders.urbanism.EntityRobotUrbanism;
import buildcraft.core.BlockIndex;
import buildcraft.core.BlockSpring;
@ -214,9 +214,9 @@ public class BuildCraftCore extends BuildCraftMod {
BCLog.initLog();
BuildcraftRecipes.assemblyTable = AssemblyRecipeManager.INSTANCE;
BuildcraftRecipes.integrationTable = IntegrationRecipeManager.INSTANCE;
BuildcraftRecipes.refinery = RefineryRecipeManager.INSTANCE;
BuildcraftRecipeRegistry.assemblyTable = AssemblyRecipeManager.INSTANCE;
BuildcraftRecipeRegistry.integrationTable = IntegrationRecipeManager.INSTANCE;
BuildcraftRecipeRegistry.refinery = RefineryRecipeManager.INSTANCE;
mainConfiguration = new BuildCraftConfiguration(new File(evt.getModConfigurationDirectory(), "buildcraft/main.conf"));
try {

View file

@ -46,7 +46,7 @@ import buildcraft.api.core.BCLog;
import buildcraft.api.core.JavaTools;
import buildcraft.api.fuels.IronEngineCoolant;
import buildcraft.api.fuels.IronEngineFuel;
import buildcraft.api.recipes.BuildcraftRecipes;
import buildcraft.api.recipes.BuildcraftRecipeRegistry;
import buildcraft.core.BlockIndex;
import buildcraft.core.BlockSpring;
import buildcraft.core.DefaultProps;
@ -258,7 +258,7 @@ public class BuildCraftEnergy extends BuildCraftMod {
BucketHandler.INSTANCE.buckets.put(blockFuel, bucketFuel);
MinecraftForge.EVENT_BUS.register(BucketHandler.INSTANCE);
BuildcraftRecipes.refinery.addRecipe(new FluidStack(fluidOil, 1), new FluidStack(fluidFuel, 1), 12, 1);
BuildcraftRecipeRegistry.refinery.addRecipe(new FluidStack(fluidOil, 1), new FluidStack(fluidFuel, 1), 12, 1);
// Iron Engine Fuels
// IronEngineFuel.addFuel("lava", 1, 20000);

View file

@ -26,7 +26,7 @@ import net.minecraftforge.oredict.OreDictionary;
import buildcraft.api.blueprints.SchematicRegistry;
import buildcraft.api.boards.RedstoneBoardRegistry;
import buildcraft.api.recipes.BuildcraftRecipes;
import buildcraft.api.recipes.BuildcraftRecipeRegistry;
import buildcraft.api.transport.PipeWire;
import buildcraft.builders.schematics.SchematicRotateMeta;
import buildcraft.core.DefaultProps;
@ -169,29 +169,44 @@ public class BuildCraftSilicon extends BuildCraftMod {
'G', BuildCraftCore.diamondGearItem);
// PIPE WIRE
BuildcraftRecipes.assemblyTable.addRecipe(500, PipeWire.RED.getStack(8), "dyeRed", 1, Items.redstone, Items.iron_ingot);
BuildcraftRecipes.assemblyTable.addRecipe(500, PipeWire.BLUE.getStack(8), "dyeBlue", 1, Items.redstone, Items.iron_ingot);
BuildcraftRecipes.assemblyTable.addRecipe(500, PipeWire.GREEN.getStack(8), "dyeGreen", 1, Items.redstone, Items.iron_ingot);
BuildcraftRecipes.assemblyTable.addRecipe(500, PipeWire.YELLOW.getStack(8), "dyeYellow", 1, Items.redstone, Items.iron_ingot);
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:redWire", 500, PipeWire.RED.getStack(8),
OreDictionary.getOres("dyeRed"), Items.redstone, Items.iron_ingot);
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:blueWire", 500, PipeWire.BLUE.getStack(8),
OreDictionary.getOres("dyeBlue"), Items.redstone, Items.iron_ingot);
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:greenWire", 500, PipeWire.GREEN.getStack(8),
OreDictionary.getOres("dyeGreen"), Items.redstone, Items.iron_ingot);
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:yellowWire", 500, PipeWire.YELLOW.getStack(8),
OreDictionary.getOres("dyeYellow"), Items.redstone, Items.iron_ingot);
// CHIPSETS
BuildcraftRecipes.assemblyTable.addRecipe(10000, Chipset.RED.getStack(), Items.redstone);
BuildcraftRecipes.assemblyTable.addRecipe(20000, Chipset.IRON.getStack(), Items.redstone, Items.iron_ingot);
BuildcraftRecipes.assemblyTable.addRecipe(40000, Chipset.GOLD.getStack(), Items.redstone, Items.gold_ingot);
BuildcraftRecipes.assemblyTable.addRecipe(80000, Chipset.DIAMOND.getStack(), Items.redstone, Items.diamond);
BuildcraftRecipes.assemblyTable.addRecipe(40000, Chipset.PULSATING.getStack(2), Items.redstone, Items.ender_pearl);
BuildcraftRecipes.assemblyTable.addRecipe(60000, Chipset.QUARTZ.getStack(), Items.redstone, Items.quartz);
BuildcraftRecipes.assemblyTable.addRecipe(60000, Chipset.COMP.getStack(), Items.redstone, Items.comparator);
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:redstoneChipset", 10000, Chipset.RED.getStack(),
Items.redstone);
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:ironChipset", 20000, Chipset.IRON.getStack(),
Items.redstone, Items.iron_ingot);
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:goldChipset", 40000, Chipset.GOLD.getStack(),
Items.redstone, Items.gold_ingot);
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:diamondChipset", 80000,
Chipset.DIAMOND.getStack(), Items.redstone, Items.diamond);
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:pulsatingChipset", 40000,
Chipset.PULSATING.getStack(2), Items.redstone, Items.ender_pearl);
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:quartzChipset", 60000, Chipset.QUARTZ.getStack(),
Items.redstone, Items.quartz);
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:compChipset", 60000, Chipset.COMP.getStack(),
Items.redstone, Items.comparator);
// GATES
BuildcraftRecipes.assemblyTable.addRecipe(10000, ItemGate.makeGateItem(GateMaterial.REDSTONE, GateLogic.AND), Chipset.RED.getStack(), PipeWire.RED.getStack());
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:simpleGate", 10000,
ItemGate.makeGateItem(GateMaterial.REDSTONE, GateLogic.AND), Chipset.RED.getStack(),
PipeWire.RED.getStack());
addGateRecipe(20000, GateMaterial.IRON, Chipset.IRON, PipeWire.RED, PipeWire.BLUE);
addGateRecipe(40000, GateMaterial.GOLD, Chipset.GOLD, PipeWire.RED, PipeWire.BLUE, PipeWire.GREEN);
addGateRecipe(80000, GateMaterial.DIAMOND, Chipset.DIAMOND, PipeWire.RED, PipeWire.BLUE, PipeWire.GREEN, PipeWire.YELLOW);
addGateRecipe("Iron", 20000, GateMaterial.IRON, Chipset.IRON, PipeWire.RED, PipeWire.BLUE);
addGateRecipe("Gold", 40000, GateMaterial.GOLD, Chipset.GOLD, PipeWire.RED, PipeWire.BLUE, PipeWire.GREEN);
addGateRecipe("Diamond", 80000, GateMaterial.DIAMOND, Chipset.DIAMOND, PipeWire.RED, PipeWire.BLUE,
PipeWire.GREEN, PipeWire.YELLOW);
// ROBOTS AND BOARDS
BuildcraftRecipes.assemblyTable.addRecipe(1000000, new ItemStack(redstoneCrystal), new ItemStack(
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:redstoneCrystal", 1000000, new ItemStack(
redstoneCrystal), new ItemStack(
Blocks.redstone_block));
CoreProxy.proxy.addCraftingRecipe(new ItemStack(redstoneBoard),
@ -209,30 +224,36 @@ public class BuildCraftSilicon extends BuildCraftMod {
'R', redstoneCrystal,
'C', Chipset.DIAMOND.getStack());
BuildcraftRecipes.assemblyTable.addRecipe(new BoardRecipe());
BuildcraftRecipes.integrationTable.addRecipe(new RobotIntegrationRecipe());
BuildcraftRecipeRegistry.assemblyTable.addRecipe(new BoardRecipe("buildcraft:redstoneBoard"));
BuildcraftRecipeRegistry.integrationTable.addRecipe(new RobotIntegrationRecipe("buildcraft:robotIntegration"));
// REVERSAL RECIPE
BuildcraftRecipes.integrationTable.addRecipe(new GateLogicSwapRecipe());
BuildcraftRecipeRegistry.integrationTable.addRecipe(new GateLogicSwapRecipe("buildcraft:gateSwap"));
// EXPANSIONS
BuildcraftRecipes.integrationTable.addRecipe(new GateExpansionRecipe(GateExpansionPulsar.INSTANCE, Chipset.PULSATING.getStack()));
BuildcraftRecipes.integrationTable.addRecipe(new GateExpansionRecipe(GateExpansionTimer.INSTANCE, Chipset.QUARTZ.getStack()));
BuildcraftRecipes.integrationTable.addRecipe(new GateExpansionRecipe(GateExpansionRedstoneFader.INSTANCE, Chipset.COMP.getStack()));
BuildcraftRecipeRegistry.integrationTable.addRecipe(new GateExpansionRecipe("buildcraft:expansionPulsar",
GateExpansionPulsar.INSTANCE, Chipset.PULSATING.getStack()));
BuildcraftRecipeRegistry.integrationTable.addRecipe(new GateExpansionRecipe("buildcraft:expansionQuartz",
GateExpansionTimer.INSTANCE, Chipset.QUARTZ.getStack()));
BuildcraftRecipeRegistry.integrationTable.addRecipe(new GateExpansionRecipe("buildcraft:expansionComp",
GateExpansionRedstoneFader.INSTANCE, Chipset.COMP.getStack()));
// FACADE
BuildcraftRecipes.integrationTable.addRecipe(new AdvancedFacadeRecipe());
BuildcraftRecipeRegistry.integrationTable.addRecipe(new AdvancedFacadeRecipe("buildcraft:advancedFacade"));
}
private static void addGateRecipe(double energyCost, GateMaterial material, Chipset chipset, PipeWire... pipeWire) {
private static void addGateRecipe(String materialName, double energyCost, GateMaterial material, Chipset chipset,
PipeWire... pipeWire) {
List temp = new ArrayList();
temp.add(chipset.getStack());
for (PipeWire wire : pipeWire) {
temp.add(wire.getStack());
}
Object[] inputs = temp.toArray();
BuildcraftRecipes.assemblyTable.addRecipe(energyCost, ItemGate.makeGateItem(material, GateLogic.AND), inputs);
BuildcraftRecipes.assemblyTable.addRecipe(energyCost, ItemGate.makeGateItem(material, GateLogic.OR), inputs);
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:andGate" + materialName, energyCost,
ItemGate.makeGateItem(material, GateLogic.AND), inputs);
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:orGate" + materialName, energyCost,
ItemGate.makeGateItem(material, GateLogic.OR), inputs);
}
@Mod.EventHandler

View file

@ -37,7 +37,7 @@ import buildcraft.api.core.IIconProvider;
import buildcraft.api.core.JavaTools;
import buildcraft.api.gates.ActionManager;
import buildcraft.api.gates.GateExpansions;
import buildcraft.api.recipes.BuildcraftRecipes;
import buildcraft.api.recipes.BuildcraftRecipeRegistry;
import buildcraft.api.transport.IExtractionHandler;
import buildcraft.api.transport.PipeManager;
import buildcraft.api.transport.PipeWire;
@ -481,7 +481,8 @@ public class BuildCraftTransport extends BuildCraftMod {
GameRegistry.addRecipe(facadeItem.new FacadeRecipe());
RecipeSorter.register("facadeTurningHelper", ItemFacade.FacadeRecipe.class, RecipeSorter.Category.SHAPELESS, "");
BuildcraftRecipes.assemblyTable.addRecipe(1000, new ItemStack(plugItem, 8), new ItemStack(pipeStructureCobblestone));
BuildcraftRecipeRegistry.assemblyTable.addRecipe("buildcraft:pipePlug", 1000, new ItemStack(plugItem, 8),
new ItemStack(pipeStructureCobblestone));
}
@Mod.EventHandler

View file

@ -72,7 +72,8 @@ public final class InterModComms {
failed = true;
} else {
NBTTagCompound recipe = msg.getNBTValue();
if (!recipe.hasKey("input", 9) || !recipe.hasKey("output", 10) || !recipe.hasKey("energy", 6)) { //Ints - NBTBase#NBTTypes
if (!recipe.hasKey("id") || !recipe.hasKey("input", 9) || !recipe.hasKey("output", 10)
|| !recipe.hasKey("energy", 6)) { // Ints - NBTBase#NBTTypes
failed = true;
} else {
NBTTagList list = (NBTTagList) recipe.getTag("input");
@ -85,7 +86,7 @@ public final class InterModComms {
}
ItemStack is = ItemStack.loadItemStackFromNBT(recipe.getCompoundTag("output"));
if (is != null && !input.isEmpty()) {
AssemblyRecipeManager.INSTANCE.addRecipe(recipe.getDouble("energy"), is,
AssemblyRecipeManager.INSTANCE.addRecipe(recipe.getString("id"), recipe.getDouble("energy"), is,
(Object[]) input.toArray(new ItemStack[input.size()]));
} else {
failed = true;
@ -141,7 +142,8 @@ public final class InterModComms {
} else {
Block block = (Block) Block.blockRegistry.getObject(blockName);
if (block.getRenderType() != 0 && block.getRenderType() != 31) {
ItemFacade.addFacade(new ItemStack(block, 1, metaId));
ItemFacade.addFacade("buildcraft:facade{" + blockName + "}",
new ItemStack(block, 1, metaId));
} else {
logRedundantAddFacadeMessage(m, block.toString());
}
@ -152,7 +154,8 @@ public final class InterModComms {
Block block = Block.getBlockFromItem(modItemStack.getItem());
if (block != null && block.getRenderType() != 0 && block.getRenderType() != 31) {
ItemFacade.addFacade(modItemStack);
ItemFacade.addFacade("buildcraft:facade{" + Block.blockRegistry.getNameForObject(block) + "}",
modItemStack);
} else {
logRedundantAddFacadeMessage(m, block.toString());
}

View file

@ -0,0 +1,83 @@
/**
* 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.core.inventory;
import java.lang.reflect.Field;
import buildcraft.api.mj.IBatteryObject;
import buildcraft.api.mj.MjBattery;
/**
* Creates a deep copy of an existing IInventory.
*
* Useful for performing inventory manipulations and then examining the results
* without affecting the original inventory.
*/
public class BatteryCopy implements IBatteryObject {
private IBatteryObject orignal;
private double contents;
public BatteryCopy(IBatteryObject orignal) {
this.orignal = orignal;
contents = orignal.getEnergyStored();
}
@Override
public double getEnergyRequested() {
return 0;
}
@Override
public double addEnergy(double mj) {
return 0;
}
@Override
public double addEnergy(double mj, boolean ignoreCycleLimit) {
return 0;
}
@Override
public double getEnergyStored() {
return contents;
}
@Override
public void setEnergyStored(double mj) {
contents = mj;
}
@Override
public double maxCapacity() {
return orignal.maxCapacity();
}
@Override
public double minimumConsumption() {
return orignal.minimumConsumption();
}
@Override
public double maxReceivedPerCycle() {
return orignal.maxReceivedPerCycle();
}
@Override
public String kind() {
return orignal.kind();
}
@Override
public void init(Object object, Field storedField, MjBattery battery) {
}
}

View file

@ -0,0 +1,66 @@
/**
* 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.core.inventory;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
public class FluidHandlerCopy implements IFluidHandler {
private IFluidHandler orignal;
private FluidTankInfo[] contents;
public FluidHandlerCopy(IFluidHandler orignal) {
this.orignal = orignal;
FluidTankInfo[] originalInfo = orignal.getTankInfo(ForgeDirection.UNKNOWN);
contents = new FluidTankInfo[originalInfo.length];
for (int i = 0; i < contents.length; i++) {
if (originalInfo[i] != null) {
contents[i] = new FluidTankInfo(originalInfo[i].fluid.copy(), originalInfo[i].capacity);
}
}
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
return 0;
}
@Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
// TODO Auto-generated method stub
return null;
}
@Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
return null;
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid) {
return orignal.canFill(from, fluid);
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid) {
return orignal.canDrain(from, fluid);
}
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection from) {
return contents;
}
}

View file

@ -19,12 +19,6 @@ public final class PacketIds {
public static final int PIPE_ITEMSTACK = 6;
public static final int PIPE_GATE_EXPANSION_MAP = 7;
public static final int SELECTION_ASSEMBLY_GET = 20;
/** Packet sent to server when a recipe is clicked on in the assembly table */
public static final int SELECTION_ASSEMBLY = 21;
/** Packet to send recipes to client */
public static final int SELECTION_ASSEMBLY_SEND = 22;
public static final int DIAMOND_PIPE_SELECT = 31;
public static final int EMERALD_PIPE_SELECT = 32;

View file

@ -291,6 +291,8 @@ public final class RPCHandler {
data.writeFloat((Float) actuals[i]);
} else if (char.class.equals(formals[i])) {
data.writeChar((Character) actuals[i]);
} else if (boolean.class.equals(formals[i])) {
data.writeBoolean((Boolean) actuals[i]);
} else {
m.mappings[i].write(data, actuals[i], context);
}
@ -317,6 +319,8 @@ public final class RPCHandler {
actuals [i] = data.readFloat();
} else if (char.class.equals(formals[i])) {
actuals [i] = data.readChar();
} else if (boolean.class.equals(formals[i])) {
actuals[i] = data.readBoolean();
} else {
actuals [i] = m.mappings [i].read (data, actuals [i], context);
}

View file

@ -13,6 +13,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -615,6 +616,7 @@ public class ClassMapping extends ClassSerializer {
static {
registerSerializer(String.class, new SerializerString());
registerSerializer(HashMap.class, new SerializerHashMap());
registerSerializer(HashSet.class, new SerializerHashSet());
registerSerializer(LinkedList.class, new SerializerLinkedList());
registerSerializer(ArrayList.class, new SerializerArrayList());
registerSerializer(Block.class, new SerializerBlock());

View file

@ -0,0 +1,59 @@
/**
* 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.core.network.serializers;
import java.util.HashSet;
import io.netty.buffer.ByteBuf;
public class SerializerHashSet extends ClassSerializer {
private static SerializerObject anonymousSerializer = new SerializerObject();
@Override
public void write(ByteBuf data, Object o, SerializationContext context)
throws IllegalArgumentException, IllegalAccessException {
HashSet set = (HashSet) o;
if (o == null) {
data.writeBoolean(false);
} else {
data.writeBoolean(true);
data.writeShort(set.size());
for (Object item : set) {
anonymousSerializer.write(data, item, context);
}
}
}
@Override
public Object read(ByteBuf data, Object o, SerializationContext context)
throws IllegalArgumentException, IllegalAccessException,
InstantiationException, ClassNotFoundException {
if (!data.readBoolean()) {
return null;
} else {
int size = data.readShort();
HashSet set = new HashSet();
for (int i = 0; i < size; ++i) {
Object value = anonymousSerializer.read(data, null, context);
set.add(value);
}
return set;
}
}
}

View file

@ -8,193 +8,52 @@
*/
package buildcraft.core.recipes;
import java.util.LinkedList;
import java.util.List;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.oredict.OreDictionary;
import buildcraft.BuildCraftCore;
import buildcraft.api.core.IInvSlot;
import buildcraft.api.recipes.IAssemblyRecipe;
import buildcraft.api.recipes.IAssemblyRecipeManager;
import buildcraft.core.inventory.ITransactor;
import buildcraft.core.inventory.InventoryIterator;
import buildcraft.core.inventory.Transactor;
import buildcraft.core.inventory.filters.ArrayStackFilter;
import buildcraft.api.recipes.IFlexibleRecipe;
public class AssemblyRecipeManager implements IAssemblyRecipeManager {
public static final AssemblyRecipeManager INSTANCE = new AssemblyRecipeManager();
private List<IAssemblyRecipe> assemblyRecipes = new LinkedList<IAssemblyRecipe>();
private Map<String, IFlexibleRecipe> assemblyRecipes = new HashMap<String, IFlexibleRecipe>();
@Override
public void addRecipe(double energyCost, ItemStack output, Object... input) {
public void addRecipe(String id, double energyCost, ItemStack output, Object... input) {
String name = Item.itemRegistry.getNameForObject(output.getItem());
if (BuildCraftCore.recipesBlacklist.contains(name)) {
return;
}
assemblyRecipes.add(new AssemblyRecipe(output, energyCost, input));
addRecipe(id, new FlexibleRecipe(id, output, energyCost, input));
}
@Override
public void addRecipe(IAssemblyRecipe recipe) {
assemblyRecipes.add(recipe);
public void addRecipe(IFlexibleRecipe recipe) {
addRecipe(recipe.getId(), recipe);
}
private void addRecipe(String id, IFlexibleRecipe recipe) {
if (assemblyRecipes.containsKey(id)) {
throw new RuntimeException("Recipe \"" + id + "\" already registered");
}
assemblyRecipes.put(recipe.getId(), recipe);
}
@Override
public List<IAssemblyRecipe> getRecipes() {
return assemblyRecipes;
public Collection<IFlexibleRecipe> getRecipes() {
return assemblyRecipes.values();
}
public static class AssemblyRecipe implements IAssemblyRecipe {
public final ItemStack output;
public final double energyCost;
private final Object[] originalInput;
private final Object[] processedInput;
public AssemblyRecipe(ItemStack output, double energyCost, Object... inputs) {
this.output = output.copy();
this.energyCost = energyCost;
this.originalInput = inputs;
processedInput = new Object[inputs.length];
for (int i = 0; i < inputs.length; i++) {
if (inputs[i] instanceof String) {
processedInput[i] = OreDictionary.getOres((String) inputs[i]);
} else if (inputs[i] instanceof ItemStack) {
processedInput[i] = inputs[i];
} else if (inputs[i] instanceof Item) {
processedInput[i] = new ItemStack((Item) inputs[i]);
} else if (inputs[i] instanceof Block) {
processedInput[i] = new ItemStack((Block) inputs[i], 1, OreDictionary.WILDCARD_VALUE);
} else if (inputs[i] instanceof Integer) {
processedInput[i] = inputs[i];
} else {
throw new IllegalArgumentException("Unknown Object passed to recipe!");
}
}
}
@Override
public ItemStack getOutput() {
return output.copy();
}
@Override
public Object[] getInputs() {
return originalInput;
}
@Override
public double getEnergyCost() {
return energyCost;
}
@Override
public boolean canBeDone(IInventory inv) {
for (int i = 0; i < processedInput.length; i++) {
if (processedInput[i] == null) {
continue;
}
if (processedInput[i] instanceof ItemStack) {
ItemStack requirement = (ItemStack) processedInput[i];
int found = 0; // Amount of ingredient found in inventory
int expected = requirement.stackSize;
for (IInvSlot slot : InventoryIterator.getIterable(inv, ForgeDirection.UNKNOWN)) {
ItemStack item = slot.getStackInSlot();
if (item == null) {
continue;
}
if (item.isItemEqual(requirement)) {
found += item.stackSize; // Adds quantity of stack to amount found
}
if (found >= expected) {
break;
}
}
// Return false if the amount of ingredient found
// is not enough
if (found < expected) {
return false;
}
} else if (processedInput[i] instanceof List) {
List<ItemStack> oreList = (List<ItemStack>) processedInput[i];
int found = 0; // Amount of ingredient found in inventory
// TODO: this i++ is highly dubious here, and against good
// programming practises. Investigate and fix or document.
//CHECKSTYLE.OFF: ModifiedControlVariable
int expected = (Integer) processedInput[i++ + 1];
//CHECKSTYLE.ON: ModifiedControlVariable
for (IInvSlot slot : InventoryIterator.getIterable(inv, ForgeDirection.UNKNOWN)) {
ItemStack item = slot.getStackInSlot();
if (item == null) {
continue;
}
for (ItemStack oreItem : oreList) {
if (OreDictionary.itemMatches(oreItem, item, true)) {
found += item.stackSize;
break;
}
}
if (found >= expected) {
break;
}
}
// Return false if the amount of ingredient found
// is not enough
if (found < expected) {
return false;
}
}
}
return true;
}
@Override
public void useItems(IInventory inv) {
ITransactor tran = Transactor.getTransactorFor(inv);
Object[] input = processedInput;
for (int i = 0; i < input.length; i++) {
if (input[i] instanceof ItemStack) {
ItemStack requirement = (ItemStack) input[i];
for (int num = 0; num < requirement.stackSize; num++) {
tran.remove(new ArrayStackFilter(requirement), ForgeDirection.UNKNOWN, true);
}
} else if (input[i] instanceof List) {
List<ItemStack> oreList = (List<ItemStack>) input[i];
int required = (Integer) input[i + 1];
for (ItemStack ore : oreList) {
for (int num = 0; num < required; num++) {
if (tran.remove(new ArrayStackFilter(ore), ForgeDirection.UNKNOWN, true) != null) {
required--;
}
}
if (required <= 0) {
break;
}
}
}
}
}
@Override
public ItemStack makeOutput() {
return getOutput().copy();
}
public IFlexibleRecipe getRecipe(String id) {
return assemblyRecipes.get(id);
}
}

View file

@ -0,0 +1,218 @@
/**
* 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.core.recipes;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.api.recipes.CraftingResult;
import buildcraft.api.recipes.IFlexibleRecipe;
import buildcraft.core.inventory.FluidHandlerCopy;
import buildcraft.core.inventory.ITransactor;
import buildcraft.core.inventory.InventoryCopy;
import buildcraft.core.inventory.Transactor;
import buildcraft.core.inventory.filters.ArrayStackFilter;
import buildcraft.core.inventory.filters.IStackFilter;
public class FlexibleRecipe implements IFlexibleRecipe {
public double energyCost = 0;
public String id;
public ItemStack outputItems = null;
public FluidStack outputFluids = null;
public ArrayList<ItemStack> inputItems = new ArrayList<ItemStack>();
public ArrayList<List<ItemStack>> inputItemsWithAlternatives = new ArrayList<List<ItemStack>>();
public ArrayList<FluidStack> inputFluids = new ArrayList<FluidStack>();
public FlexibleRecipe() {
}
public FlexibleRecipe(String id, Object output, double iEnergyCost, Object... input) {
setContents(id, output, iEnergyCost, input);
}
public void setContents(String iid, Object output, double iEnergyCost, Object... input) {
id = iid;
if (output instanceof ItemStack) {
outputItems = (ItemStack) output;
} else if (output instanceof Item) {
outputItems = new ItemStack((Item) output);
} else if (output instanceof Block) {
outputItems = new ItemStack((Block) output);
} else if (output instanceof FluidStack) {
outputFluids = (FluidStack) output;
} else {
throw new IllegalArgumentException("Unknown Object passed to recipe!");
}
energyCost = iEnergyCost;
for (Object i : input) {
if (i instanceof ItemStack) {
inputItems.add((ItemStack) i);
} else if (i instanceof Item) {
inputItems.add(new ItemStack((Item) i));
} else if (i instanceof Block) {
inputItems.add(new ItemStack((Block) i));
} else if (i instanceof FluidStack) {
inputFluids.add((FluidStack) i);
} else if (i instanceof List) {
inputItemsWithAlternatives.add((List) i);
} else {
throw new IllegalArgumentException("Unknown Object passed to recipe!");
}
}
}
@Override
public boolean canBeCrafted(IInventory items, IFluidHandler fluids) {
return craftPreview(items, fluids) != null;
}
@Override
public final CraftingResult craftPreview(IInventory items, IFluidHandler fluids) {
return craft(items == null ? null : new InventoryCopy(items),
fluids == null ? null : new FluidHandlerCopy(fluids));
}
@Override
public CraftingResult craft(IInventory items, IFluidHandler fluids) {
CraftingResult result = new CraftingResult();
result.recipe = this;
result.energyCost = energyCost;
// Item simple stacks consumption
if (items == null && inputItems.size() > 0) {
return null;
}
if (items != null) {
ITransactor tran = Transactor.getTransactorFor(items);
for (ItemStack requirement : inputItems) {
IStackFilter filter = new ArrayStackFilter(requirement);
for (int num = 0; num < requirement.stackSize; num++) {
ItemStack s = tran.remove(filter, ForgeDirection.UNKNOWN, true);
if (s == null) {
return null;
} else {
result.usedItems.add(s);
}
}
}
}
// Item stacks with alternatives consumption
if (items == null && inputItemsWithAlternatives.size() > 0) {
return null;
}
if (items != null) {
ITransactor tran = Transactor.getTransactorFor(items);
for (List<ItemStack> requirements : inputItemsWithAlternatives) {
int required = requirements.get(0).stackSize;
IStackFilter filter = new ArrayStackFilter(requirements.toArray(new ItemStack [0]));
for (int num = 0; num < required; num++) {
ItemStack s = tran.remove(filter, ForgeDirection.UNKNOWN, true);
if (s != null) {
result.usedItems.add(s);
required--;
if (required == 0) {
break;
}
}
}
if (required > 0) {
return null;
}
}
}
// Fluid stacks consumption
if (fluids == null && inputFluids.size() > 0) {
return null;
}
if (fluids != null) {
for (FluidStack requirement : inputFluids) {
for (FluidTankInfo info : fluids.getTankInfo(ForgeDirection.UNKNOWN)) {
if (info.fluid.isFluidEqual(requirement)) {
int amountUsed = 0;
if (info.fluid.amount > requirement.amount) {
requirement.amount = 0;
info.fluid.amount -= requirement.amount;
amountUsed += requirement.amount;
} else {
requirement.amount -= info.fluid.amount;
info.fluid.amount = 0;
amountUsed += info.fluid.amount;
}
result.usedFluids.add(new FluidStack(requirement.fluidID, amountUsed));
}
}
}
}
for (FluidStack requirement : inputFluids) {
if (requirement.amount > 0) {
return null;
}
}
// Output generation
if (outputItems != null) {
result.crafted = outputItems;
return result;
} else if (outputFluids != null) {
result.crafted = outputFluids;
return result;
} else {
return null;
}
}
@Override
public String getId() {
return id;
}
}

View file

@ -11,20 +11,20 @@ package buildcraft.core.recipes;
import java.util.LinkedList;
import java.util.List;
import buildcraft.api.recipes.IIntegrationRecipe;
import buildcraft.api.recipes.IIntegrationRecipeFactory;
import buildcraft.api.recipes.IIntegrationRecipeManager;
public class IntegrationRecipeManager implements IIntegrationRecipeManager {
public static final IntegrationRecipeManager INSTANCE = new IntegrationRecipeManager();
private List<IIntegrationRecipe> integrationRecipes = new LinkedList<IIntegrationRecipe>();
private List<IIntegrationRecipeFactory> integrationRecipes = new LinkedList<IIntegrationRecipeFactory>();
@Override
public void addRecipe(IIntegrationRecipe recipe) {
public void addRecipe(IIntegrationRecipeFactory recipe) {
integrationRecipes.add(recipe);
}
@Override
public List<? extends IIntegrationRecipe> getRecipes() {
public List<? extends IIntegrationRecipeFactory> getRecipes() {
return integrationRecipes;
}
}

View file

@ -8,15 +8,26 @@
*/
package buildcraft.core.robots;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.BuildCraftSilicon;
import buildcraft.api.recipes.IIntegrationRecipe;
import buildcraft.api.recipes.CraftingResult;
import buildcraft.api.recipes.IIntegrationRecipeFactory;
import buildcraft.core.ItemRobot;
import buildcraft.core.recipes.FlexibleRecipe;
import buildcraft.core.utils.NBTUtils;
import buildcraft.silicon.ItemRedstoneBoard;
public class RobotIntegrationRecipe implements IIntegrationRecipe {
public class RobotIntegrationRecipe extends FlexibleRecipe implements IIntegrationRecipeFactory {
public RobotIntegrationRecipe(String id) {
setContents(id, new ItemStack(BuildCraftSilicon.robotItem), 10000, new ItemStack(
BuildCraftSilicon.redstoneBoard));
}
@Override
public boolean isValidInputA(ItemStack inputA) {
return inputA != null && inputA.getItem() instanceof ItemRobot;
@ -28,11 +39,19 @@ public class RobotIntegrationRecipe implements IIntegrationRecipe {
}
@Override
public IntegrationResult integrate(ItemStack inputA, ItemStack inputB, ItemStack[] components) {
ItemStack robot = new ItemStack(BuildCraftSilicon.robotItem);
public CraftingResult craft(IInventory items, IFluidHandler fluids) {
CraftingResult result = super.craft(items, fluids);
NBTUtils.getItemData(robot).setTag("board", NBTUtils.getItemData(inputB));
if (result != null) {
ItemStack robot = new ItemStack(BuildCraftSilicon.robotItem);
return IntegrationResult.create(10000, robot);
NBTUtils.getItemData(robot).setTag("board", NBTUtils.getItemData(items.getStackInSlot(1)));
result.crafted = robot;
return result;
} else {
return null;
}
}
}

View file

@ -8,29 +8,30 @@
*/
package buildcraft.silicon;
import java.util.LinkedHashSet;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import cpw.mods.fml.common.FMLCommonHandler;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.BuildCraftSilicon;
import buildcraft.api.recipes.IAssemblyRecipe;
import buildcraft.core.DefaultProps;
import buildcraft.api.core.NetworkData;
import buildcraft.api.recipes.CraftingResult;
import buildcraft.api.recipes.IFlexibleRecipe;
import buildcraft.core.IMachine;
import buildcraft.core.network.PacketIds;
import buildcraft.core.network.PacketNBT;
import buildcraft.core.network.PacketUpdate;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCSide;
import buildcraft.core.recipes.AssemblyRecipeManager;
import buildcraft.core.triggers.ActionMachineControl;
import buildcraft.core.utils.StringUtils;
@ -38,36 +39,22 @@ import buildcraft.core.utils.Utils;
public class TileAssemblyTable extends TileLaserTableBase implements IMachine, IInventory {
public IAssemblyRecipe currentRecipe;
private Set<IAssemblyRecipe> plannedOutput = new LinkedHashSet<IAssemblyRecipe>();
@NetworkData
private HashSet<String> plannedOutput = new HashSet<String>();
public static class SelectionMessage {
@NetworkData
public String currentRecipeId = "";
public boolean select;
public ItemStack stack;
public IFlexibleRecipe currentRecipe;
public NBTTagCompound getNBT() {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setBoolean("s", select);
NBTTagCompound itemNBT = new NBTTagCompound();
stack.writeToNBT(itemNBT);
nbt.setTag("i", itemNBT);
return nbt;
}
public List<CraftingResult> getPotentialOutputs() {
List<CraftingResult> result = new LinkedList<CraftingResult>();
public void fromNBT(NBTTagCompound nbt) {
select = nbt.getBoolean("s");
NBTTagCompound itemNBT = nbt.getCompoundTag("i");
stack = ItemStack.loadItemStackFromNBT(itemNBT);
}
}
for (IFlexibleRecipe recipe : AssemblyRecipeManager.INSTANCE.getRecipes()) {
CraftingResult r = recipe.craftPreview(this, null);
public List<IAssemblyRecipe> getPotentialOutputs() {
List<IAssemblyRecipe> result = new LinkedList<IAssemblyRecipe>();
for (IAssemblyRecipe recipe : AssemblyRecipeManager.INSTANCE.getRecipes()) {
if (recipe.canBeDone(this)) {
result.add(recipe);
if (r != null) {
result.add(r);
}
}
@ -82,11 +69,12 @@ public class TileAssemblyTable extends TileLaserTableBase implements IMachine, I
@Override
public void updateEntity() { // WARNING: run only server-side, see canUpdate()
super.updateEntity();
if (currentRecipe == null) {
return;
}
if (!currentRecipe.canBeDone(this)) {
if (!currentRecipe.canBeCrafted(this, null)) {
setNextCurrentRecipe();
if (currentRecipe == null) {
@ -94,13 +82,12 @@ public class TileAssemblyTable extends TileLaserTableBase implements IMachine, I
}
}
if (getEnergy() >= currentRecipe.getEnergyCost() && lastMode != ActionMachineControl.Mode.Off) {
if (getEnergy() >= currentRecipe.craftPreview(this, null).energyCost
&& lastMode != ActionMachineControl.Mode.Off) {
setEnergy(0);
if (currentRecipe.canBeDone(this)) {
currentRecipe.useItems(this);
ItemStack remaining = currentRecipe.makeOutput();
if (currentRecipe.canBeCrafted(this, null)) {
ItemStack remaining = (ItemStack) currentRecipe.craft(this, null).crafted;
remaining.stackSize -= Utils.addToRandomInventoryAround(worldObj, xCoord, yCoord, zCoord, remaining);
if (remaining.stackSize > 0) {
@ -143,34 +130,21 @@ public class TileAssemblyTable extends TileLaserTableBase implements IMachine, I
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
NBTTagList list = nbt.getTagList("planned", Constants.NBT.TAG_COMPOUND);
NBTTagList list = nbt.getTagList("plannedIds", Constants.NBT.TAG_STRING);
for (int i = 0; i < list.tagCount(); ++i) {
NBTTagCompound cpt = list.getCompoundTagAt(i);
IFlexibleRecipe recipe = AssemblyRecipeManager.INSTANCE.getRecipe(list.getStringTagAt(i));
ItemStack stack = ItemStack.loadItemStackFromNBT(cpt);
if (stack == null) {
continue;
}
for (IAssemblyRecipe r : AssemblyRecipeManager.INSTANCE.getRecipes()) {
if (r.getOutput().getItem() == stack.getItem()
&& r.getOutput().getItemDamage() == stack.getItemDamage()) {
plannedOutput.add(r);
break;
}
if (recipe != null) {
plannedOutput.add(recipe.getId());
}
}
if (nbt.hasKey("recipe")) {
ItemStack stack = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("recipe"));
if (nbt.hasKey("recipeId")) {
IFlexibleRecipe recipe = AssemblyRecipeManager.INSTANCE.getRecipe(nbt.getString("recipeId"));
for (IAssemblyRecipe r : plannedOutput) {
if (r.getOutput().getItem() == stack.getItem()
&& r.getOutput().getItemDamage() == stack.getItemDamage()) {
setCurrentRecipe(r);
break;
}
if (recipe != null) {
setCurrentRecipe(recipe);
}
}
}
@ -181,48 +155,61 @@ public class TileAssemblyTable extends TileLaserTableBase implements IMachine, I
NBTTagList list = new NBTTagList();
for (IAssemblyRecipe recipe : plannedOutput) {
NBTTagCompound cpt = new NBTTagCompound();
recipe.getOutput().writeToNBT(cpt);
list.appendTag(cpt);
for (String recipe : plannedOutput) {
list.appendTag(new NBTTagString(recipe));
}
nbt.setTag("planned", list);
nbt.setTag("plannedIds", list);
if (currentRecipe != null) {
NBTTagCompound recipe = new NBTTagCompound();
currentRecipe.getOutput().writeToNBT(recipe);
nbt.setTag("recipe", recipe);
nbt.setString("recipeId", currentRecipe.getId());
}
}
public boolean isPlanned(IAssemblyRecipe recipe) {
public boolean isPlanned(IFlexibleRecipe recipe) {
if (recipe == null) {
return false;
}
return plannedOutput.contains(recipe);
return plannedOutput.contains(recipe.getId());
}
public boolean isAssembling(IAssemblyRecipe recipe) {
public boolean isAssembling(IFlexibleRecipe recipe) {
return recipe != null && recipe == currentRecipe;
}
private void setCurrentRecipe(IAssemblyRecipe recipe) {
this.currentRecipe = recipe;
private void setCurrentRecipe(IFlexibleRecipe recipe) {
currentRecipe = recipe;
if (recipe != null) {
currentRecipeId = recipe.getId();
} else {
currentRecipeId = "";
}
if (!worldObj.isRemote) {
sendNetworkUpdate();
}
}
@Override
public double getRequiredEnergy() {
if (currentRecipe != null) {
return currentRecipe.getEnergyCost();
CraftingResult result = currentRecipe.craftPreview(this, null);
if (result != null) {
return result.energyCost;
} else {
return 0;
}
} else {
return 0;
}
return 0;
}
public void planOutput(IAssemblyRecipe recipe) {
public void planOutput(IFlexibleRecipe recipe) {
if (recipe != null && !isPlanned(recipe)) {
plannedOutput.add(recipe);
plannedOutput.add(recipe.getId());
if (!isAssembling(currentRecipe) || !isPlanned(currentRecipe)) {
setCurrentRecipe(recipe);
@ -230,32 +217,36 @@ public class TileAssemblyTable extends TileLaserTableBase implements IMachine, I
}
}
public void cancelPlanOutput(IAssemblyRecipe recipe) {
public void cancelPlanOutput(IFlexibleRecipe recipe) {
if (isAssembling(recipe)) {
setCurrentRecipe(null);
}
plannedOutput.remove(recipe);
plannedOutput.remove(recipe.getId());
if (!plannedOutput.isEmpty()) {
setCurrentRecipe(plannedOutput.iterator().next());
setCurrentRecipe(AssemblyRecipeManager.INSTANCE.getRecipe(plannedOutput.iterator().next()));
}
}
public void setNextCurrentRecipe() {
boolean takeNext = false;
for (IAssemblyRecipe recipe : plannedOutput) {
for (String recipeId : plannedOutput) {
IFlexibleRecipe recipe = AssemblyRecipeManager.INSTANCE.getRecipe(recipeId);
if (recipe == currentRecipe) {
takeNext = true;
} else if (takeNext && recipe.canBeDone(this)) {
} else if (takeNext && recipe.canBeCrafted(this, null)) {
setCurrentRecipe(recipe);
return;
}
}
for (IAssemblyRecipe recipe : plannedOutput) {
if (recipe.canBeDone(this)) {
for (String recipeId : plannedOutput) {
IFlexibleRecipe recipe = AssemblyRecipeManager.INSTANCE.getRecipe(recipeId);
if (recipe.canBeCrafted(this, null)) {
setCurrentRecipe(recipe);
return;
}
@ -264,41 +255,23 @@ public class TileAssemblyTable extends TileLaserTableBase implements IMachine, I
setCurrentRecipe(null);
}
public void handleSelectionMessage(SelectionMessage message) {
for (IAssemblyRecipe recipe : AssemblyRecipeManager.INSTANCE.getRecipes()) {
if (recipe.getOutput().isItemEqual(message.stack)
&& ItemStack.areItemStackTagsEqual(recipe.getOutput(), message.stack)) {
if (message.select) {
planOutput(recipe);
} else {
cancelPlanOutput(recipe);
}
break;
}
}
public void rpcSelectRecipe(String id, boolean select) {
RPCHandler.rpcServer(this, "selectRecipe", id, select);
}
public void sendSelectionTo(EntityPlayer player) {
for (IAssemblyRecipe recipe : AssemblyRecipeManager.INSTANCE.getRecipes()) {
SelectionMessage message = new SelectionMessage();
@RPC(RPCSide.SERVER)
private void selectRecipe(String id, boolean select) {
IFlexibleRecipe recipe = AssemblyRecipeManager.INSTANCE.getRecipe(id);
message.stack = recipe.getOutput();
if (isPlanned(recipe)) {
message.select = true;
if (recipe != null) {
if (select) {
planOutput(recipe);
} else {
message.select = false;
cancelPlanOutput(recipe);
}
PacketNBT packet = new PacketNBT(PacketIds.SELECTION_ASSEMBLY_SEND, message.getNBT(), xCoord, yCoord, zCoord);
packet.posX = xCoord;
packet.posY = yCoord;
packet.posZ = zCoord;
// FIXME: This needs to be switched over to new synch system.
BuildCraftSilicon.instance.sendToPlayers(packet, worldObj, (int) player.posX, (int) player.posY, (int) player.posZ,
DefaultProps.NETWORK_UPDATE_RANGE);
}
sendNetworkUpdate();
}
@Override
@ -320,4 +293,10 @@ public class TileAssemblyTable extends TileLaserTableBase implements IMachine, I
public boolean hasCustomInventoryName() {
return false;
}
@Override
public void postPacketHandling(PacketUpdate packet) {
currentRecipe = AssemblyRecipeManager.INSTANCE.getRecipe(currentRecipeId);
}
}

View file

@ -14,8 +14,10 @@ import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.recipes.BuildcraftRecipes;
import buildcraft.api.recipes.IIntegrationRecipe;
import buildcraft.api.recipes.BuildcraftRecipeRegistry;
import buildcraft.api.recipes.CraftingResult;
import buildcraft.api.recipes.IFlexibleRecipe;
import buildcraft.api.recipes.IIntegrationRecipeFactory;
import buildcraft.core.inventory.ITransactor;
import buildcraft.core.inventory.InventoryMapper;
import buildcraft.core.inventory.SimpleInventory;
@ -31,12 +33,13 @@ public class TileIntegrationTable extends TileLaserTableBase implements ISidedIn
public static final int SLOT_INPUT_B = 1;
public static final int SLOT_OUTPUT = 2;
private static final int CYCLE_LENGTH = 32;
private static final int[] SLOTS = Utils.createSlotArray(0, 3);
private static final int[] SLOT_COMPONENTS = Utils.createSlotArray(3, 9);
private final int[] SLOTS = Utils.createSlotArray(0, 3);
private final int[] SLOT_COMPONENTS = Utils.createSlotArray(3, 9);
private int tick = 0;
private SimpleInventory invRecipeOutput = new SimpleInventory(1, "integrationOutput", 64);
private InventoryMapper invOutput = new InventoryMapper(inv, SLOT_OUTPUT, 1, false);
private IIntegrationRecipe.IntegrationResult integrationResult;
private IFlexibleRecipe activeRecipe;
private CraftingResult craftingPreview;
private boolean canCraft = false;
public IInventory getRecipeOutput() {
@ -69,58 +72,49 @@ public class TileIntegrationTable extends TileLaserTableBase implements ISidedIn
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) {
setNewActiveRecipe(inputA, inputB, components);
if (activeRecipe == null || craftingPreview == null) {
setEnergy(0);
return;
}
invRecipeOutput.setInventorySlotContents(0, integrationResult.output);
invRecipeOutput.setInventorySlotContents(0, (ItemStack) craftingPreview.crafted);
if (!isRoomForOutput(integrationResult.output)) {
if (!isRoomForOutput((ItemStack) craftingPreview.crafted)) {
setEnergy(0);
return;
}
canCraft = true;
if (getEnergy() >= integrationResult.energyCost && lastMode != ActionMachineControl.Mode.Off) {
if (getEnergy() >= craftingPreview.energyCost
&& lastMode != ActionMachineControl.Mode.Off) {
setEnergy(0);
inv.decrStackSize(SLOT_INPUT_A, 1);
inv.decrStackSize(SLOT_INPUT_B, 1);
craftingPreview = null;
// For each required component, loop through the component inventory
for (ItemStack stack : integrationResult.usedComponents) {
int decreased = 0;
for (int i = SLOT_OUTPUT + 1; i < 12; i++) {
ItemStack stack1 = inv.getStackInSlot(i);
CraftingResult craftResult = activeRecipe.craft(this, null);
if (stack1 != null) {
if (StackHelper.isMatchingItem(stack, stack1, true, false)) {
decreased += stack1.stackSize;
inv.decrStackSize(i, stack.stackSize - decreased);
}
}
if (decreased >= stack.stackSize) {
break;
}
}
if (craftResult != null) {
ItemStack result = (ItemStack) craftResult.crafted;
ITransactor trans = Transactor.getTransactorFor(invOutput);
trans.add(result, ForgeDirection.UP, true);
}
ITransactor trans = Transactor.getTransactorFor(invOutput);
trans.add(integrationResult.output, ForgeDirection.UP, true);
}
}
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) &&
(result = recipe.integrate(inputA, inputB, components)) != null) {
return result;
private void setNewActiveRecipe(ItemStack inputA, ItemStack inputB, ItemStack[] components) {
for (IIntegrationRecipeFactory recipe : BuildcraftRecipeRegistry.integrationTable.getRecipes()) {
if (recipe.isValidInputA(inputA) && recipe.isValidInputB(inputB)) {
craftingPreview = recipe.craftPreview(this, null);
if (craftingPreview != null) {
activeRecipe = recipe;
break;
}
}
}
return null;
}
private boolean isRoomForOutput(ItemStack output) {
@ -136,10 +130,17 @@ public class TileIntegrationTable extends TileLaserTableBase implements ISidedIn
@Override
public double getRequiredEnergy() {
if (integrationResult != null) {
return integrationResult.energyCost;
if (activeRecipe != null) {
CraftingResult result = activeRecipe.craftPreview(this, null);
if (result != null) {
return result.energyCost;
} else {
return 0;
}
} else {
return 0;
}
return 0.0;
}
@Override
@ -160,7 +161,7 @@ public class TileIntegrationTable extends TileLaserTableBase implements ISidedIn
private boolean isValidInputA(ItemStack stack) {
ItemStack inputB = inv.getStackInSlot(SLOT_INPUT_B);
for (IIntegrationRecipe recipe : BuildcraftRecipes.integrationTable.getRecipes()) {
for (IIntegrationRecipeFactory recipe : BuildcraftRecipeRegistry.integrationTable.getRecipes()) {
if (recipe.isValidInputA(stack) && (inputB == null || recipe.isValidInputB(inputB))) {
return true;
}
@ -170,7 +171,7 @@ public class TileIntegrationTable extends TileLaserTableBase implements ISidedIn
private boolean isValidInputB(ItemStack stack) {
ItemStack inputA = inv.getStackInSlot(SLOT_INPUT_A);
for (IIntegrationRecipe recipe : BuildcraftRecipes.integrationTable.getRecipes()) {
for (IIntegrationRecipeFactory recipe : BuildcraftRecipeRegistry.integrationTable.getRecipes()) {
if (recipe.isValidInputB(stack) && (inputA == null || recipe.isValidInputA(inputA))) {
return true;
}
@ -190,7 +191,8 @@ public class TileIntegrationTable extends TileLaserTableBase implements ISidedIn
@Override
public boolean canExtractItem(int slot, ItemStack stack, int side) {
return slot == SLOT_OUTPUT;
// return slot == SLOT_OUTPUT;
return true;
}
@Override
@ -210,7 +212,7 @@ public class TileIntegrationTable extends TileLaserTableBase implements ISidedIn
@Override
public boolean isActive() {
return integrationResult != null && super.isActive();
return activeRecipe != null && super.isActive();
}
}

View file

@ -11,101 +11,38 @@ package buildcraft.silicon.boards;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.BuildCraftSilicon;
import buildcraft.api.boards.RedstoneBoardRegistry;
import buildcraft.api.core.IInvSlot;
import buildcraft.api.recipes.IAssemblyRecipe;
import buildcraft.core.inventory.ITransactor;
import buildcraft.core.inventory.InventoryIterator;
import buildcraft.core.inventory.Transactor;
import buildcraft.core.inventory.filters.ArrayStackFilter;
import buildcraft.api.recipes.CraftingResult;
import buildcraft.core.recipes.FlexibleRecipe;
import buildcraft.core.utils.NBTUtils;
public class BoardRecipe implements IAssemblyRecipe {
public class BoardRecipe extends FlexibleRecipe {
private ItemStack[] inputs;
private ItemStack output;
public BoardRecipe () {
inputs = new ItemStack[] {
new ItemStack(BuildCraftSilicon.redstoneBoard)};
output = new ItemStack(BuildCraftSilicon.redstoneBoard);
public BoardRecipe(String id) {
ItemStack output = new ItemStack(BuildCraftSilicon.redstoneBoard);
NBTUtils.getItemData(output).setString("id", "<unknown>");
setContents(id, output, 1000, new ItemStack(BuildCraftSilicon.redstoneBoard));
}
@Override
public ItemStack getOutput() {
return output;
}
public CraftingResult craft(IInventory items, IFluidHandler fluids) {
CraftingResult result = super.craft(items, fluids);
@Override
public ItemStack makeOutput() {
ItemStack stack = new ItemStack(BuildCraftSilicon.redstoneBoard);
RedstoneBoardRegistry.instance.createRandomBoard(NBTUtils.getItemData(stack));
if (result != null) {
ItemStack stack = new ItemStack(BuildCraftSilicon.redstoneBoard);
RedstoneBoardRegistry.instance.createRandomBoard(NBTUtils.getItemData(stack));
return stack;
}
result.crafted = stack;
@Override
public Object[] getInputs() {
return inputs;
}
@Override
public double getEnergyCost() {
return 10000;
}
// FIXME: canBeDone and useItems could use some improvements and
// factorization. See AssemblyRecipe as well.
@Override
public boolean canBeDone(IInventory inv) {
for (ItemStack requirement : inputs) {
if (requirement == null) {
continue;
}
int found = 0; // Amount of ingredient found in inventory
int expected = requirement.stackSize;
for (IInvSlot slot : InventoryIterator.getIterable(inv, ForgeDirection.UNKNOWN)) {
ItemStack item = slot.getStackInSlot();
if (item == null) {
continue;
}
if (item.isItemEqual(requirement)) {
found += item.stackSize; // Adds quantity of stack to
// amount found
}
if (found >= expected) {
break;
}
}
// Return false if the amount of ingredient found
// is not enough
if (found < expected) {
return false;
}
}
return true;
}
@Override
public void useItems(IInventory inv) {
ITransactor tran = Transactor.getTransactorFor(inv);
for (ItemStack requirement : inputs) {
for (int num = 0; num < requirement.stackSize; num++) {
tran.remove(new ArrayStackFilter(requirement), ForgeDirection.UNKNOWN, true);
}
return result;
} else {
return null;
}
}
}

View file

@ -15,14 +15,11 @@ import net.minecraft.inventory.Slot;
import buildcraft.core.gui.BuildCraftContainer;
import buildcraft.silicon.TileAssemblyTable;
import buildcraft.silicon.TileAssemblyTable.SelectionMessage;
public class ContainerAssemblyTable extends BuildCraftContainer {
IInventory playerIInventory;
TileAssemblyTable table;
boolean networkSynchronized = false;
public ContainerAssemblyTable(IInventory playerInventory, TileAssemblyTable table) {
super(table.getSizeInventory());
this.playerIInventory = playerInventory;
@ -53,10 +50,6 @@ public class ContainerAssemblyTable extends BuildCraftContainer {
return table.isUseableByPlayer(entityplayer);
}
public void handleSelectionMessage(SelectionMessage message) {
table.handleSelectionMessage(message);
}
@Override
public void updateProgressBar(int i, int j) {
table.getGUINetworkData(i, j);

View file

@ -20,18 +20,13 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import buildcraft.BuildCraftCore;
import buildcraft.BuildCraftSilicon;
import buildcraft.api.recipes.IAssemblyRecipe;
import buildcraft.api.recipes.CraftingResult;
import buildcraft.core.CoreIconProvider;
import buildcraft.core.DefaultProps;
import buildcraft.core.gui.AdvancedSlot;
import buildcraft.core.gui.GuiAdvancedInterface;
import buildcraft.core.network.PacketCoordinates;
import buildcraft.core.network.PacketIds;
import buildcraft.core.network.PacketNBT;
import buildcraft.core.utils.StringUtils;
import buildcraft.silicon.TileAssemblyTable;
import buildcraft.silicon.TileAssemblyTable.SelectionMessage;
public class GuiAssemblyTable extends GuiAdvancedInterface {
@ -80,8 +75,7 @@ public class GuiAssemblyTable extends GuiAdvancedInterface {
private final TileAssemblyTable table;
class RecipeSlot extends AdvancedSlot {
public IAssemblyRecipe recipe;
public CraftingResult crafting;
public RecipeSlot(int x, int y) {
super(GuiAssemblyTable.this, x, y);
@ -89,8 +83,8 @@ public class GuiAssemblyTable extends GuiAdvancedInterface {
@Override
public ItemStack getItemStack() {
if (this.recipe != null) {
return this.recipe.getOutput();
if (crafting != null) {
return (ItemStack) crafting.crafted;
} else {
return null;
}
@ -116,23 +110,17 @@ public class GuiAssemblyTable extends GuiAdvancedInterface {
}
updateRecipes();
// Request current selection from server
if (assemblyTable.getWorldObj().isRemote) {
BuildCraftSilicon.instance.sendToServer(new PacketCoordinates(PacketIds.SELECTION_ASSEMBLY_GET, assemblyTable.xCoord, assemblyTable.yCoord,
assemblyTable.zCoord));
}
}
public void updateRecipes() {
List<IAssemblyRecipe> potentialRecipes = table.getPotentialOutputs();
Iterator<IAssemblyRecipe> cur = potentialRecipes.iterator();
List<CraftingResult> potentialRecipes = table.getPotentialOutputs();
Iterator<CraftingResult> cur = potentialRecipes.iterator();
for (int p = 0; p < 8; ++p) {
if (cur.hasNext()) {
((RecipeSlot) slots[p]).recipe = cur.next();
((RecipeSlot) slots[p]).crafting = cur.next();
} else {
((RecipeSlot) slots[p]).recipe = null;
((RecipeSlot) slots[p]).crafting = null;
}
}
}
@ -159,10 +147,12 @@ public class GuiAssemblyTable extends GuiAdvancedInterface {
for (AdvancedSlot slot2 : slots) {
RecipeSlot slot = (RecipeSlot) slot2;
if (table.isAssembling(slot.recipe)) {
drawTexturedModalRect(cornerX + slot.x, cornerY + slot.y, 196, 1, 16, 16);
} else if (table.isPlanned(slot.recipe)) {
drawTexturedModalRect(cornerX + slot.x, cornerY + slot.y, 177, 1, 16, 16);
if (slot.crafting != null) {
if (table.isAssembling(slot.crafting.recipe)) {
drawTexturedModalRect(cornerX + slot.x, cornerY + slot.y, 196, 1, 16, 16);
} else if (table.isPlanned(slot.crafting.recipe)) {
drawTexturedModalRect(cornerX + slot.x, cornerY + slot.y, 177, 1, 16, 16);
}
}
}
@ -185,26 +175,21 @@ public class GuiAssemblyTable extends GuiAdvancedInterface {
if (position != -1) {
RecipeSlot slot = (RecipeSlot) slots[position];
if (slot.recipe == null) {
if (slot.crafting == null) {
return;
}
SelectionMessage message = new SelectionMessage();
boolean select;
if (table.isPlanned(slot.recipe)) {
table.cancelPlanOutput(slot.recipe);
message.select = false;
if (table.isPlanned(slot.crafting.recipe)) {
select = false;
} else {
table.planOutput(slot.recipe);
message.select = true;
select = true;
}
message.stack = slot.recipe.getOutput();
String id = slot.crafting.recipe.getId();
if (table.getWorldObj().isRemote) {
PacketNBT packet = new PacketNBT(PacketIds.SELECTION_ASSEMBLY, message.getNBT(), table.xCoord, table.yCoord, table.zCoord);
BuildCraftSilicon.instance.sendToServer(packet);
}
table.rpcSelectRecipe(id, select);
}
}

View file

@ -13,7 +13,6 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.network.INetHandler;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
@ -21,15 +20,11 @@ import net.minecraft.world.World;
import cpw.mods.fml.common.network.NetworkRegistry;
import buildcraft.core.network.BuildCraftPacket;
import buildcraft.core.network.PacketCoordinates;
import buildcraft.core.network.PacketIds;
import buildcraft.core.network.PacketNBT;
import buildcraft.core.network.PacketSlotChange;
import buildcraft.core.proxy.CoreProxy;
import buildcraft.silicon.TileAdvancedCraftingTable;
import buildcraft.silicon.TileAssemblyTable;
import buildcraft.silicon.TileAssemblyTable.SelectionMessage;
import buildcraft.silicon.gui.ContainerAssemblyTable;
@Sharable
public class PacketHandlerSilicon extends SimpleChannelInboundHandler<BuildCraftPacket> {
@ -44,15 +39,6 @@ public class PacketHandlerSilicon extends SimpleChannelInboundHandler<BuildCraft
int packetID = packet.getID();
switch (packetID) {
case PacketIds.SELECTION_ASSEMBLY_SEND:
onSelectionUpdate(player, (PacketNBT) packet);
break;
case PacketIds.SELECTION_ASSEMBLY:
onAssemblySelect(player, (PacketNBT) packet);
break;
case PacketIds.SELECTION_ASSEMBLY_GET:
onAssemblyGetSelection(player, (PacketCoordinates) packet);
break;
case PacketIds.ADVANCED_WORKBENCH_SETSLOT:
onAdvancedWorkbenchSet(player, (PacketSlotChange) packet);
break;
@ -64,17 +50,6 @@ public class PacketHandlerSilicon extends SimpleChannelInboundHandler<BuildCraft
}
private void onSelectionUpdate(EntityPlayer player, PacketNBT packet) {
Container container = player.openContainer;
if (container instanceof ContainerAssemblyTable) {
SelectionMessage message = new SelectionMessage();
message.fromNBT(packet.getTagCompound());
((ContainerAssemblyTable) container).handleSelectionMessage(message);
}
}
private TileAssemblyTable getAssemblyTable(World world, int x, int y, int z) {
if (!world.blockExists(x, y, z)) {
@ -103,40 +78,6 @@ public class PacketHandlerSilicon extends SimpleChannelInboundHandler<BuildCraft
return (TileAdvancedCraftingTable) tile;
}
/**
* Sends the current selection on the assembly table to a player.
*
* @param player
* @param packet
*/
private void onAssemblyGetSelection(EntityPlayer player, PacketCoordinates packet) {
TileAssemblyTable tile = getAssemblyTable(player.worldObj, packet.posX, packet.posY, packet.posZ);
if (tile == null) {
return;
}
tile.sendSelectionTo(player);
}
/**
* Sets the selection on an assembly table according to player request.
*
* @param player
* @param packetA
*/
private void onAssemblySelect(EntityPlayer player, PacketNBT packetA) {
TileAssemblyTable tile = getAssemblyTable(player.worldObj, packetA.posX, packetA.posY, packetA.posZ);
if (tile == null) {
return;
}
TileAssemblyTable.SelectionMessage message = new TileAssemblyTable.SelectionMessage();
message.fromNBT(packetA.getTagCompound());
tile.handleSelectionMessage(message);
}
/**
* Sets the packet into the advanced workbench
*

View file

@ -8,20 +8,29 @@
*/
package buildcraft.silicon.recipes;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.IFluidHandler;
import net.minecraftforge.oredict.OreDictionary;
import buildcraft.BuildCraftTransport;
import buildcraft.api.core.JavaTools;
import buildcraft.api.recipes.IIntegrationRecipe;
import buildcraft.api.recipes.CraftingResult;
import buildcraft.api.recipes.IIntegrationRecipeFactory;
import buildcraft.api.transport.PipeWire;
import buildcraft.core.recipes.FlexibleRecipe;
import buildcraft.silicon.ItemRedstoneChipset;
import buildcraft.silicon.TileIntegrationTable;
import buildcraft.transport.ItemFacade;
import buildcraft.transport.ItemPipeWire;
public class AdvancedFacadeRecipe implements IIntegrationRecipe {
private final ItemStack[] requiredComponents = new ItemStack[] {new ItemStack(BuildCraftTransport.pipeWire, 1, OreDictionary.WILDCARD_VALUE), ItemRedstoneChipset.Chipset.RED.getStack()};
public class AdvancedFacadeRecipe extends FlexibleRecipe implements IIntegrationRecipeFactory {
public AdvancedFacadeRecipe(String id) {
setContents(id, new ItemFacade(), 5000,
new ItemStack(BuildCraftTransport.pipeWire, 1, OreDictionary.WILDCARD_VALUE),
ItemRedstoneChipset.Chipset.RED.getStack());
}
@Override
public boolean isValidInputA(ItemStack inputA) {
@ -35,24 +44,29 @@ public class AdvancedFacadeRecipe implements IIntegrationRecipe {
}
@Override
public IntegrationResult integrate(ItemStack inputA, ItemStack inputB, ItemStack[] components) {
if (!IntegrationResult.enoughComponents(components, requiredComponents)) {
public CraftingResult craft(IInventory items, IFluidHandler fluids) {
CraftingResult result = super.craft(items, fluids);
if (result == null) {
return null;
}
PipeWire wire = null;
for (ItemStack stack : components) {
ItemStack inputA = items.getStackInSlot(TileIntegrationTable.SLOT_INPUT_A);
ItemStack inputB = items.getStackInSlot(TileIntegrationTable.SLOT_INPUT_B);
for (ItemStack stack : result.usedItems) {
if (stack != null && stack.getItem() instanceof ItemPipeWire) {
wire = PipeWire.fromOrdinal(stack.getItemDamage());
break;
}
}
if (wire != null) {
ItemFacade.FacadeState[] states = ItemFacade.getFacadeStates(inputA);
ItemFacade.FacadeState additionalState;
if (inputB.getItem() == BuildCraftTransport.plugItem) {
additionalState = ItemFacade.FacadeState.createTransparent(wire);
} else {
@ -64,11 +78,19 @@ public class AdvancedFacadeRecipe implements IIntegrationRecipe {
for (int i = 0; i < states.length; i++) {
if (states[i].wire == wire) {
states[i] = additionalState;
return IntegrationResult.create(2000, ItemFacade.getFacade(states), requiredComponents);
result.energyCost = 2000;
result.crafted = ItemFacade.getFacade(states);
return result;
}
}
// otherwise concat all states into one facade
return IntegrationResult.create(5000, ItemFacade.getFacade(JavaTools.concat(states, new ItemFacade.FacadeState[] {additionalState})), requiredComponents);
result.energyCost = 5000;
result.crafted = ItemFacade.getFacade(JavaTools.concat(states,
new ItemFacade.FacadeState[] {additionalState}));
return result;
} else {
return null;
}

View file

@ -8,31 +8,41 @@
*/
package buildcraft.silicon.recipes;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.BuildCraftTransport;
import buildcraft.api.gates.IGateExpansion;
import buildcraft.api.recipes.IIntegrationRecipe;
import buildcraft.api.recipes.CraftingResult;
import buildcraft.api.recipes.IIntegrationRecipeFactory;
import buildcraft.core.inventory.StackHelper;
import buildcraft.core.recipes.FlexibleRecipe;
import buildcraft.silicon.TileIntegrationTable;
import buildcraft.transport.gates.ItemGate;
public class GateExpansionRecipe implements IIntegrationRecipe {
public class GateExpansionRecipe extends FlexibleRecipe implements IIntegrationRecipeFactory {
private final IGateExpansion expansion;
private final ItemStack chipset;
public GateExpansionRecipe(IGateExpansion expansion, ItemStack chipset) {
public GateExpansionRecipe(String id, IGateExpansion expansion, ItemStack chipset) {
this.expansion = expansion;
this.chipset = chipset.copy();
setContents(id, BuildCraftTransport.pipeGate, 10000, BuildCraftTransport.pipeGate, chipset);
}
@Override
public boolean isValidInputA(ItemStack inputA) {
if (inputA == null) {
return false;
}
if (!(inputA.getItem() instanceof ItemGate)) {
} else if (!(inputA.getItem() instanceof ItemGate)) {
return false;
} else {
return !ItemGate.hasGateExpansion(inputA, expansion);
}
return !ItemGate.hasGateExpansion(inputA, expansion);
}
@Override
@ -41,10 +51,28 @@ public class GateExpansionRecipe implements IIntegrationRecipe {
}
@Override
public IntegrationResult integrate(ItemStack inputA, ItemStack inputB, ItemStack[] components) {
ItemStack output = inputA.copy();
public CraftingResult craft(IInventory items, IFluidHandler fluids) {
ItemStack inputA = items.getStackInSlot(TileIntegrationTable.SLOT_INPUT_A);
if (inputA == null) {
return null;
}
inputA = inputA.copy();
CraftingResult result = super.craft(items, fluids);
if (result == null) {
return null;
}
ItemStack output = inputA;
output.stackSize = 1;
ItemGate.addGateExpansion(output, expansion);
return IntegrationResult.create(10000, output);
result.crafted = output;
return result;
}
}

View file

@ -8,16 +8,28 @@
*/
package buildcraft.silicon.recipes;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import buildcraft.api.recipes.IIntegrationRecipe;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.BuildCraftTransport;
import buildcraft.api.recipes.CraftingResult;
import buildcraft.api.recipes.IIntegrationRecipeFactory;
import buildcraft.core.inventory.StackHelper;
import buildcraft.core.recipes.FlexibleRecipe;
import buildcraft.silicon.ItemRedstoneChipset;
import buildcraft.silicon.TileIntegrationTable;
import buildcraft.transport.gates.GateDefinition.GateLogic;
import buildcraft.transport.gates.GateDefinition.GateMaterial;
import buildcraft.transport.gates.ItemGate;
public class GateLogicSwapRecipe implements IIntegrationRecipe {
public class GateLogicSwapRecipe extends FlexibleRecipe implements IIntegrationRecipeFactory {
public GateLogicSwapRecipe(String id) {
setContents(id, BuildCraftTransport.pipeGate, 2000, BuildCraftTransport.pipeGate);
}
@Override
public boolean isValidInputA(ItemStack inputA) {
return inputA != null && inputA.getItem() instanceof ItemGate && ItemGate.getMaterial(inputA) != GateMaterial.REDSTONE;
@ -29,10 +41,22 @@ public class GateLogicSwapRecipe implements IIntegrationRecipe {
}
@Override
public IntegrationResult integrate(ItemStack inputA, ItemStack inputB, ItemStack[] components) {
ItemStack output = inputA.copy();
public CraftingResult craft(IInventory items, IFluidHandler fluids) {
ItemStack inputA = items.getStackInSlot(TileIntegrationTable.SLOT_INPUT_A).copy();
CraftingResult result = super.craft(items, fluids);
if (result == null) {
return null;
}
ItemStack output = (ItemStack) result.crafted;
output.stackSize = 1;
ItemGate.setLogic(output, ItemGate.getLogic(output) == GateLogic.AND ? GateLogic.OR : GateLogic.AND);
return IntegrationResult.create(2000, output);
result.crafted = output;
return result;
}
}

View file

@ -37,7 +37,7 @@ import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.BuildCraftTransport;
import buildcraft.api.core.JavaTools;
import buildcraft.api.core.Position;
import buildcraft.api.recipes.BuildcraftRecipes;
import buildcraft.api.recipes.BuildcraftRecipeRegistry;
import buildcraft.api.transport.PipeWire;
import buildcraft.core.BlockSpring;
import buildcraft.core.CreativeTabBuildCraft;
@ -242,11 +242,11 @@ public class ItemFacade extends ItemBuildCraft {
continue;
}
registerValidFacades(b, item);
registerValidFacades("buildcraft:facade{" + Block.blockRegistry.getNameForObject(b) + "}", b, item);
}
}
private static void registerValidFacades(Block block, Item item) {
private static void registerValidFacades(String id, Block block, Item item) {
Set<String> names = Sets.newHashSet();
for (int i = 0; i <= 15; i++) {
@ -255,7 +255,7 @@ public class ItemFacade extends ItemBuildCraft {
if (!Strings.isNullOrEmpty(stack.getUnlocalizedName())
&& names.add(stack.getUnlocalizedName())) {
ItemFacade.addFacade(stack);
ItemFacade.addFacade(id, stack);
// prevent adding multiple facades if it's a rotatable block
if (block.getRenderType() == 31) {
@ -399,7 +399,7 @@ public class ItemFacade extends ItemBuildCraft {
return true;
}
public static void addFacade(ItemStack itemStack) {
public static void addFacade(String id, ItemStack itemStack) {
if (itemStack.stackSize == 0) {
itemStack.stackSize = 1;
}
@ -412,7 +412,8 @@ public class ItemFacade extends ItemBuildCraft {
facade6.stackSize = 6;
// 3 Structurepipes + this block makes 6 facades
BuildcraftRecipes.assemblyTable.addRecipe(8000, facade6, new ItemStack(BuildCraftTransport.pipeStructureCobblestone, 3), itemStack);
BuildcraftRecipeRegistry.assemblyTable.addRecipe(id, 8000, facade6, new ItemStack(
BuildCraftTransport.pipeStructureCobblestone, 3), itemStack);
}
}