Do you mean you want a SINGLE slot to be able to burn through TWO or more items at a time? If that's the case, then you will need 3 integer values per ItemStack as the key in your HashMap.
map.put(Arrays.asList(itemID, metadata, stacksize, ... repeat 3 parameters per itemstack), itemStackYouWantToReturn);
Of course you'd have to update the other methods to account for the change in number of parameters.
package mods.B0bGary.B0bCraft.recipe;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
public class AlloyerRecipes
{
public AlloyerRecipes()
{
}
public static ItemStack getSmeltingResult(ItemStack i, ItemStack j)
{
return getOutput(i, j);
}
private static ItemStack getOutput(ItemStack i, ItemStack j)
{
if (i == new ItemStack (Item.coal, 1, 1) && j == new ItemStack (Item.ingotIron, 1, 0) || j == new ItemStack (Item.coal, 1, 1) && i == new ItemStack (Item.ingotIron, 1, 0))
{
return new ItemStack(Item.ingotGold, 1);
}
return null;
}
}
That's all my recipe class is at the moment. What method did that code go into?
So... what's the problem you're having? Other than it's not working for dual input, can you give any more detail? I'm not sure if you saw, but I have a tutorial on this issue that covers all the information that should be necessary to convert a normal furnace into a dual or more input furnace. Perhaps reading through that (again, if necessary) will help clear some things up.
That's all my recipe class is at the moment. What method did that code go into?
Yeah, so I'll get back to you after you read through the tutorial a couple times. That recipe class needs a lot of work.
For future reference, DON'T ever do this:
if (i == new ItemStack (Item.coal, 1, 1))
That is checking if the object 'i' which you got from an argument is equal to a NEW object you create on the spot; how could that possibly return true? Well, if it was a base type like int, but then you wouldn't be using 'new' would you? You could try:
if (i.equals(new ItemStack(Item.coal, 1, 1))
But even that is dodgy and could very easily give you unexpected results. Better to use:
if (i.itemID == Item.coal.itemID) or, in preparation for 1.7, something like if (i.getItem() == Item.coal) or comparing Item names or whatever.
Or for that matter the rest of your statement; when you have two distinct logic components, they must be isolated from each other by parentheses, so you can have:
if (a && { // do something }
if ((a && || (c && d)) { // do something }
Note that if all of your logic operators are the same, then the parentheses are unnecessary:
if (a && b && c && d) { }
if (a || b || c || d) { }
But as soon as you start mixing them up, you need to be very careful setting up your statement's logic scope (using parentheses) or it will probably do things very differently from what you expect.
Yeah, so I'll get back to you after you read through the tutorial a couple times. That recipe class needs a lot of work.
For future reference, DON'T ever do this:
if (i == new ItemStack (Item.coal, 1, 1))
That is checking if the object 'i' which you got from an argument is equal to a NEW object you create on the spot; how could that possibly return true? Well, if it was a base type like int, but then you wouldn't be using 'new' would you? You could try:
if (i.equals(new ItemStack(Item.coal, 1, 1))
But even that is dodgy and could very easily give you unexpected results. Better to use:
if (i.itemID == Item.coal.itemID) or, in preparation for 1.7, something like if (i.getItem() == Item.coal) or comparing Item names or whatever.
Or for that matter the rest of your statement; when you have two distinct logic components, they must be isolated from each other by parentheses, so you can have:
if (a && { // do something }
if ((a && || (c && d)) { // do something }
Note that if all of your logic operators are the same, then the parentheses are unnecessary:
if (a && b && c && d) { }
if (a || b || c || d) { }
But as soon as you start mixing them up, you need to be very careful setting up your statement's logic scope (using parentheses) or it will probably do things very differently from what you expect.
Ok. All that code was based off the tutorial.
In my tile entity, it has this method (based off the tutorial):
Which brings you to the getSmeltingResult method.
The vanilla method is
public ItemStack getSmeltingResult(ItemStack item)
{
if (item == null)
{
return null;
}
ItemStack ret = (ItemStack)metaSmeltingList.get(Arrays.asList(item.itemID, item.getItemDamage()));
if (ret != null)
{
return ret;
}
return (ItemStack)smeltingList.get(Integer.valueOf(item.itemID));
}
Obviously mine needs to have the double input. This is what I have so far:
public ItemStack getSmeltingResult(ItemStack item, ItemStack item2)
{
if (item==null||item2==null)
{
return null;
}
ItemStack ret = (ItemStack)metaSmeltingList.get(Arrays.asList(item.itemID, item.getItemDamage(), Arrays.asList(item2.itemID, item2.getItemDamage())));
if (ret != null)
{
return ret;
}
return (ItemStack)smeltingList.get(Integer.valueOf(item.itemID));
}
Which isn't working so I've done something wrong.
Whole Recipe class
package mods.B0bGary.B0bCraft.recipe;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import mods.B0bGary.B0bCraft.Base;
import mods.B0bGary.B0bCraft.inventory.ContainerAlloyer;
import net.minecraft.item.ItemStack;
public class AlloyerRecipes
{
private static final AlloyerRecipes smeltingBase = new AlloyerRecipes();
// This creates a HashMap whose Key is a specific, ordered List of Integers
// If you want multiple outputs from one recipe, change the ItemStack to an ItemStack[]
// (and of course adjust your TileEntity and Container code)
private HashMap<List<Integer>, ItemStack> metaSmeltingList = new HashMap<List<Integer>, ItemStack>();
private Map smeltingList = new HashMap();
// Same as above except it gives us the experience for each crafting result
private HashMap<List<Integer>, Float> metaExperience = new HashMap<List<Integer>, Float>();
/**
* Used to call methods addInscribing and getInscribingResult.
*/
public static final AlloyerRecipes smelting() {
return smeltingBase;
}
/**
* Adds all recipes to the HashMap
*/
private AlloyerRecipes()
{
this.addSmelting(Arrays.asList(Base.ingot.itemID, 0, Base.ingot.itemID, 1), new ItemStack(Base.ingot.itemID, 1, 3), 0.3F);
}
public void addSmelting(List<Integer> items, ItemStack out, float experience)
{
metaSmeltingList.put(items, out);
metaExperience.put(Arrays.asList(out.itemID, out.getItemDamage()), experience);
}
/**
* Used to get the resulting ItemStack form a source ItemStack
* @param item The Source ItemStack
* @return The result ItemStack
*/
public ItemStack getSmeltingResult(ItemStack item, ItemStack item2)
{
if (item==null||item2==null)
{
return null;
}
ItemStack ret = (ItemStack)metaSmeltingList.get(Arrays.asList(item.itemID, item.getItemDamage(), Arrays.asList(item2.itemID, item2.getItemDamage())));
if (ret != null)
{
return ret;
}
return (ItemStack)smeltingList.get(Integer.valueOf(item.itemID));
}
/**
* Grabs the amount of base experience for this item to give when pulled from the furnace slot.
*/
public float getExperience(ItemStack item)
{
if (item == null || item.getItem() == null)
{
return 0;
}
float ret = -1; // value returned by "item.getItem().getSmeltingExperience(item);" when item doesn't specify experience to give
if (ret < 0 && metaExperience.containsKey(Arrays.asList(item.itemID, item.getItemDamage())))
{
ret = metaExperience.get(Arrays.asList(item.itemID, item.getItemDamage()));
}
return (ret < 0 ? 0 : ret);
}
public Map<List<Integer>, ItemStack> getMetaInscribingList()
{
return metaSmeltingList;
}
}
Whole Tile Entity
package mods.B0bGary.B0bCraft.tileentity;
import cpw.mods.fml.common.registry.GameRegistry;
import mods.B0bGary.B0bCraft.recipe.AlloyerRecipes;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
public class TileEntityAlloyer extends TileEntity implements IInventory
{
private ItemStack blastItemStacks[];
public int dualBurnTime;
public int currentItemBurnTime;
public int dualCookTime;
private String customName;
public TileEntityAlloyer()
{
blastItemStacks = new ItemStack[4];
dualBurnTime = 0;
currentItemBurnTime = 0;
dualCookTime = 0;
}
/**
* Returns the number of slots in the inventory.
*/
public int getSizeInventory()
{
return blastItemStacks.length;
}
/**
* Returns the stack in slot i
*/
public ItemStack getStackInSlot(int i)
{
return blastItemStacks[i];
}
public void setInventorySlotConatainers(int i, ItemStack itemstack)
{
blastItemStacks[i] = itemstack;
if (itemstack != null && itemstack.stackSize > getInventoryStackLimit())
{
itemstack.stackSize = getInventoryStackLimit();
}
}
/**
* Reads a tile entity from NBT.
*/
public void readFromNBT(NBTTagCompound nbttagcompound)
{
super.readFromNBT(nbttagcompound);
NBTTagList nbttaglist = nbttagcompound.getTagList("Items");
blastItemStacks = new ItemStack[getSizeInventory()];
for (int i = 0; i < nbttaglist.tagCount(); i++)
{
NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i);
byte byte0 = nbttagcompound1.getByte("Slot");
if (byte0 >= 0 && byte0 < blastItemStacks.length)
{
blastItemStacks[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
}
}
dualBurnTime = nbttagcompound.getShort("BurnTime");
dualCookTime = nbttagcompound.getShort("CookTime");
currentItemBurnTime = getItemBurnTime(blastItemStacks[1]);
}
/**
* Writes a tile entity to NBT.
*/
public void writeToNBT(NBTTagCompound nbttagcompound)
{
super.writeToNBT(nbttagcompound);
nbttagcompound.setShort("BurnTime", (short)dualBurnTime);
nbttagcompound.setShort("CookTime", (short)dualCookTime);
NBTTagList nbttaglist = new NBTTagList();
for (int i = 0; i < blastItemStacks.length; i++)
{
if (blastItemStacks[i] != null)
{
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
nbttagcompound1.setByte("Slot", (byte)i);
blastItemStacks[i].writeToNBT(nbttagcompound1);
nbttaglist.appendTag(nbttagcompound1);
}
}
nbttagcompound.setTag("Items", nbttaglist);
}
/**
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't
* this more of a set than a get?*
*/
public int getInventoryStackLimit()
{
return 64;
}
public int getCookProgressScaled(int i)
{
return (dualCookTime * i) / 200;
}
public int getBurnTimeRemainingScaled(int i)
{
if (currentItemBurnTime == 0)
{
currentItemBurnTime = 200;
}
return (dualBurnTime * i) / currentItemBurnTime;
}
public boolean isBurning()
{
return dualBurnTime > 0;
}
/**
* Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count
* ticks and creates a new spawn inside its implementation.
*/
public void updateEntity()
{
boolean flag = dualBurnTime > 0;
boolean flag1 = false;
if (dualBurnTime > 0)
{
dualBurnTime--;
}
if (!worldObj.isRemote)
{
if (dualBurnTime == 0 && canSmelt())
{
currentItemBurnTime = dualBurnTime = getItemBurnTime(blastItemStacks[2]);
if (dualBurnTime > 0)
{
flag1 = true;
if (blastItemStacks[2] != null)
{
if (blastItemStacks[2].stackSize == 0)
{
blastItemStacks[2] = new ItemStack(blastItemStacks[2].getItem().setFull3D());
}
else
{
blastItemStacks[2].stackSize--;
}
if (blastItemStacks[2].stackSize == 0)
{
blastItemStacks[2] = null;
}
}
}
}
if (isBurning() && canSmelt())
{
dualCookTime++;
if (dualCookTime == 200)
{
dualCookTime = 0;
smeltItem();
flag1 = true;
}
}
else
{
dualCookTime = 0;
}
if (flag != (dualBurnTime > 0))
{
flag1 = true;
}
}
if (flag1)
{
onInventoryChanged();
}
}
private boolean canSmelt()
{
if (blastItemStacks[0] == null || blastItemStacks[1] == null)
{
return false;
}
ItemStack itemstack = AlloyerRecipes.smelting().getSmeltingResult(blastItemStacks[0], blastItemStacks[1]);
if (itemstack == null)
{
return false;
}
if (blastItemStacks[3] == null)
{
return true;
}
if (!blastItemStacks[3].isItemEqual(itemstack))
{
return false;
}
if (blastItemStacks[3].stackSize < getInventoryStackLimit() && blastItemStacks[3].stackSize < blastItemStacks[3].getMaxStackSize())
{
return true;
}
else
{
return blastItemStacks[3].stackSize < itemstack.getMaxStackSize();
}
}
public void smeltItem()
{
if (!canSmelt())
{
return;
}
ItemStack itemstack = AlloyerRecipes.smelting().getSmeltingResult(blastItemStacks[0], blastItemStacks[1]);
if (blastItemStacks[3] == null)
{
blastItemStacks[3] = itemstack.copy();
}
else if (blastItemStacks[3].itemID == itemstack.itemID)
{
blastItemStacks[3].stackSize++;
}
for (int i = 0; i < 2; i++)
{
if (blastItemStacks[i].stackSize <= 0)
{
blastItemStacks[i] = new ItemStack(blastItemStacks[i].getItem().setFull3D());
}
else
{
blastItemStacks[i].stackSize--;
}
if (blastItemStacks[i].stackSize <= 0)
{
blastItemStacks[i] = null;
}
}
}
private int getItemBurnTime(ItemStack itemstack)
{
if (itemstack == null)
{
return 0;
}
int i = itemstack.getItem().itemID;
if (i < 256 && Block.blocksList[i].blockMaterial == Material.wood)
{
return 300;
}
if (i == Item.stick.itemID)
{
return 100;
}
if (i == Item.coal.itemID)
{
return 1600;
}
if (i == Item.bucketLava.itemID)
{
return 20000;
}
if (i == Item.blazeRod.itemID)
{
return 2400;
}
if (i == Block.sapling.blockID)
{
return 100;
}
else
{
return GameRegistry.getFuelValue(itemstack);
}
}
/**
* Do not make give this method the name canInteractWith because it clashes with Container
*/
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
if (worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) != this)
{
return false;
}
else
{
return entityplayer.getDistanceSq((double)xCoord + 0.5D, (double)yCoord + 0.5D, (double)zCoord + 0.5D) <= 64D;
}
}
/**
* Decrease the size of the stack in slot (first int arg) by the amount of the second int arg. Returns the new
* stack.
*/
public ItemStack decrStackSize(int i, int j)
{
if (blastItemStacks[i] != null)
{
if (blastItemStacks[i].stackSize <= j)
{
ItemStack itemstack = blastItemStacks[i];
blastItemStacks[i] = null;
return itemstack;
}
ItemStack itemstack1 = blastItemStacks[i].splitStack(j);
if (blastItemStacks[i].stackSize == 0)
{
blastItemStacks[i] = null;
}
return itemstack1;
}
else
{
return null;
}
}
/**
* Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
*/
public void setInventorySlotContents(int i, ItemStack itemstack)
{
blastItemStacks[i] = itemstack;
if (itemstack != null && itemstack.stackSize > getInventoryStackLimit())
{
itemstack.stackSize = getInventoryStackLimit();
}
}
/**
* Returns the name of the inventory.
*/
public String getInvName()
{
return "Alloyer";
}
public void openChest()
{
}
public void closeChest()
{
}
/**
* When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem -
* like when you close a workbench GUI.
*/
public ItemStack getStackInSlotOnClosing(int i)
{
if (blastItemStacks[i] != null)
{
ItemStack itemstack = blastItemStacks[i];
blastItemStacks[i] = null;
return itemstack;
}
else
{
return null;
}
}
@Override
public boolean isInvNameLocalized()
{
return (this.customName != null) && (this.customName.length() > 0);
}
public void setCustomName(String name)
{
this.customName = name;
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
return false;
}
public void setGuiDisplayName(String displayName) {
displayName="Alloyer";
}
}
Ok, your new code is much better Your problem is probably here:
ItemStack ret = (ItemStack)metaSmeltingList.get(Arrays.asList(item.itemID, item.getItemDamage(), Arrays.asList(item2.itemID, item2.getItemDamage())));
Notice how you call 'Arrays.asList' twice, which should be giving you an error in your code. Remember that a HashMap key is a single object, be it an integer, a String, or in our case, a List of integers, so when you call the put method you used a single ArrayList correctly which creates the key, you need to use that same exact key when retrieving the object:
// This is the correct Array.asList you used to create the key initially
put(Arrays.asList(Base.ingot.itemID, 0, Base.ingot.itemID, 1)
// so use a similar, single array list to retrieve the stored object from your HashMap
get(Arrays.asList(item1.itemID, item1.getItemDamage(), item2.itemID, item2.getItemDamage())
Ok, your new code is much better Your problem is probably here:
ItemStack ret = (ItemStack)metaSmeltingList.get(Arrays.asList(item.itemID, item.getItemDamage(), Arrays.asList(item2.itemID, item2.getItemDamage())));
Notice how you call 'Arrays.asList' twice, which should be giving you an error in your code. Remember that a HashMap key is a single object, be it an integer, a String, or in our case, a List of integers, so when you call the put method you used a single ArrayList correctly which creates the key, you need to use that same exact key when retrieving the object:
// This is the correct Array.asList you used to create the key initially
put(Arrays.asList(Base.ingot.itemID, 0, Base.ingot.itemID, 1)
// so use a similar, single array list to retrieve the stored object from your HashMap
get(Arrays.asList(item1.itemID, item1.getItemDamage(), item2.itemID, item2.getItemDamage())
Oh thankyou! I was having the exact same problem for the longest time! Thanks again!
@HackerTdog....first thing I can see is in the block class you have some references to your tile and also tilefurnace...deleting the imports would show you all the things that need corrected.
A Protected class can only be used by its parent or child classes, it can't be used outside of that scope. In the first furnace tutorial (the youtube videos), the BlockFurnace class in the source code is a PUBLIC class, not Protected. You're probably getting that error because the compiler assumes you're trying to call a protected class that can't be accessed by the main code file.
I want to say thanks to microjunk for this very useful series of tutorials on making custom furnaces. I have searched several other sites for this information, but good info is few and far between. Most tutorials are for older versions of Minecraft, or don't cover enough to be actually useable for someone new to making their own furnaces.
I have a trouble with simple furnace, when I go to GUI furnace in game I can't do anything with items/blocks, even move it. Also GUI doesn't open when in method onBlockActivated present condition "if (par1World.isRemote)", but it always true and code below doesn't execute. What I'm doing wrong? I have done all that saw in video tutorial...
I am having trouble doubling my output for the dual input furnace. Basically, I want two items each time I cook and I get the two on the first pass, but subsequent ones are only one.
Here is my recipe file:
package net.smeltercraft.mod.crafting;
import net.smeltercraft.mod.SmelterCraft;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
public class RotaryKilnRecipes
{
public RotaryKilnRecipes()
{
}
public static ItemStack getSmeltingResult(int i, int j)
{
return getOutput(i, j);
}
private static ItemStack getOutput(int i, int j)
{
if (i == SmelterCraft.itemRawCuprum.itemID && j == SmelterCraft.itemRawStannum.itemID || i == SmelterCraft.itemRawStannum.itemID && j == SmelterCraft.itemRawCuprum.itemID)
{
return new ItemStack(SmelterCraft.itemRawBronze, 2);
}
if (i == SmelterCraft.rotaryKiln1 && j == SmelterCraft.rotaryKiln2 || i == SmelterCraft.rotaryKiln2 && j == SmelterCraft.rotaryKiln1)
{
return new ItemStack(SmelterCraft.itemRawBronze, 2);
}
return null;
}
}
Edit: Figured out my problem, it was in the tileentitiy.
Hey!
Your tutorial is great!
I used another tutorial first and i used like 5 months on it. It never worked and i was not even half way!
When i found this tutorial and did it in 2 days!!!
I made it working but when i make two furnaces the first would not open the gui.
I copied the first furnace. I think its same ID in both of the furnaces thats why only the furnace dont work.
Where is the problem?
Hey, so in registering two different furnaces, you need to change the GUI ID for the GUI handler class! That way it can tell which one to open. How, or more like, where do I change the GUI ID? Thanks in advanced!
Hey, so in registering two different furnaces, you need to change the GUI ID for the GUI handler class! That way it can tell which one to open. How, or more like, where do I change the GUI ID? Thanks in advanced!
Usually it will be under your block class.
Look for a line this under your onBlockActivated method:
If you have been following Micro's tuts, it is most likely 0. Change that and you should be to go. Let me know how it comes out and don't forget to make sure it matches what you put for it in the GuiHandler!
If you have been following Micro's tuts, it is most likely 0. Change that and you should be to go. Let me know how it comes out and don't forget to make sure it matches what you put for it in the GuiHandler!
I am having an issue where when I click on my furnace nothing happens. Absolutely nothing. I have every class from the tutorial videos and no errors and still, nothing pops up. Not even a line of code in the log. Any thoughts? (This is for the single furnace, based on the videos)
Guys, i need some help. I am trying to recreate an anvil but I've hit a brick wall and have been stuck for weeks!
I have copied all of the anvil class to get the model and tweaked minor things to do with textures. But when i try to do gui, nothing happens. The best I have been able to do is get the gui open but you must be holding something and you can't move any of your items.
I haven't found a tile entity class so i can't recreate the gui.
If anyone can help, it would be highly appreciative,
Oh, I am in 1.6.4 aswell!
T3chnGam3r
I've played around a bit and only had the same problems as a best result, hopefully some help comes.
Hello. I have a working dual input furnace but am having some issues with hopper automation. Ingredients will insert fine but fuel will insert into the smelting slots and the main problem is that hoppers pull out my fuel and ingredients. I've tried looking into the TileEntityFurnace as well as TileEntityBrewingStand to try to find a solution but nothing is working. Here are my custom TileEntity and Container classes; Let me know if you guys need any other classes. Thanks in advance!
public class TileEntityAlembic extends TileEntity implements IInventory
{
private ItemStack blastItemStacks[];
public int dualBurnTime;
public int currentItemBurnTime;
public int dualCookTime;
private String customName;
private static final int[] slots_top = new int[] {0, 1};
private static final int[] slots_bottom = new int[] {3};
private static final int[] slots_sides = new int[] {2};
public TileEntityAlembic()
{
blastItemStacks = new ItemStack[4];
dualBurnTime = 0;
currentItemBurnTime = 0;
dualCookTime = 0;
}
/**
* Returns the number of slots in the inventory.
*/
public int getSizeInventory()
{
return blastItemStacks.length;
}
/**
* Returns the stack in slot i
*/
public ItemStack getStackInSlot(int i)
{
return blastItemStacks[i];
}
public void setInventorySlotConatainers(int i, ItemStack itemstack)
{
blastItemStacks[i] = itemstack;
if (itemstack != null && itemstack.stackSize > getInventoryStackLimit())
{
itemstack.stackSize = getInventoryStackLimit();
}
}
/**
* Reads a tile entity from NBT.
*/
public void readFromNBT(NBTTagCompound nbttagcompound)
{
super.readFromNBT(nbttagcompound);
NBTTagList nbttaglist = nbttagcompound.getTagList("Items");
blastItemStacks = new ItemStack[getSizeInventory()];
for (int i = 0; i < nbttaglist.tagCount(); i++)
{
NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i);
byte byte0 = nbttagcompound1.getByte("Slot");
if (byte0 >= 0 && byte0 < blastItemStacks.length)
{
blastItemStacks[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
}
}
dualBurnTime = nbttagcompound.getShort("BurnTime");
dualCookTime = nbttagcompound.getShort("CookTime");
currentItemBurnTime = getItemBurnTime(blastItemStacks[1]);
}
/**
* Writes a tile entity to NBT.
*/
public void writeToNBT(NBTTagCompound nbttagcompound)
{
super.writeToNBT(nbttagcompound);
nbttagcompound.setShort("BurnTime", (short)dualBurnTime);
nbttagcompound.setShort("CookTime", (short)dualCookTime);
NBTTagList nbttaglist = new NBTTagList();
for (int i = 0; i < blastItemStacks.length; i++)
{
if (blastItemStacks[i] != null)
{
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
nbttagcompound1.setByte("Slot", (byte)i);
blastItemStacks[i].writeToNBT(nbttagcompound1);
nbttaglist.appendTag(nbttagcompound1);
}
}
nbttagcompound.setTag("Items", nbttaglist);
}
/**
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't
* this more of a set than a get?*
*/
public int getInventoryStackLimit()
{
return 64;
}
public int getCookProgressScaled(int i)
{
return (dualCookTime * i) / 200;
}
public int getBurnTimeRemainingScaled(int i)
{
if (currentItemBurnTime == 0)
{
currentItemBurnTime = 200;
}
return (dualBurnTime * i) / currentItemBurnTime;
}
public boolean isBurning()
{
return dualBurnTime > 0;
}
/**
* Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count
* ticks and creates a new spawn inside its implementation.
*/
public void updateEntity()
{
boolean flag = dualBurnTime > 0;
boolean flag1 = false;
if (dualBurnTime > 0)
{
dualBurnTime--;
}
if (!worldObj.isRemote)
{
if (dualBurnTime == 0 && canSmelt())
{
currentItemBurnTime = dualBurnTime = getItemBurnTime(blastItemStacks[2]);
if (dualBurnTime > 0)
{
flag1 = true;
if (blastItemStacks[2] != null)
{
if (blastItemStacks[2].stackSize == 0)
{
blastItemStacks[2] = new ItemStack(blastItemStacks[2].getItem().setFull3D());
}
else
{
blastItemStacks[2].stackSize--;
}
if (blastItemStacks[2].stackSize == 0)
{
blastItemStacks[2] = null;
}
}
}
}
if (isBurning() && canSmelt())
{
dualCookTime++;
if (dualCookTime == 200)
{
dualCookTime = 0;
smeltItem();
flag1 = true;
}
}
else
{
dualCookTime = 0;
}
if (flag != (dualBurnTime > 0))
{
flag1 = true;
}
}
if (flag1)
{
onInventoryChanged();
}
}
private boolean canSmelt()
{
if (blastItemStacks[0] == null || blastItemStacks[1] == null)
{
return false;
}
ItemStack itemstack = AlembicRecipes.getSmeltingResult(blastItemStacks[0].getItem().itemID, blastItemStacks[1].getItem().itemID);
if (itemstack == null)
{
return false;
}
if (blastItemStacks[3] == null)
{
return true;
}
if (!blastItemStacks[3].isItemEqual(itemstack))
{
return false;
}
if (blastItemStacks[3].stackSize < getInventoryStackLimit() && blastItemStacks[3].stackSize < blastItemStacks[3].getMaxStackSize())
{
return true;
}
else
{
return blastItemStacks[3].stackSize < itemstack.getMaxStackSize();
}
}
public void smeltItem()
{
if (!canSmelt())
{
return;
}
ItemStack itemstack = AlembicRecipes.getSmeltingResult(blastItemStacks[0].getItem().itemID, blastItemStacks[1].getItem().itemID);
if (blastItemStacks[3] == null)
{
blastItemStacks[3] = itemstack.copy();
}
else if (blastItemStacks[3].itemID == itemstack.itemID)
{
blastItemStacks[3].stackSize++;
}
for (int i = 0; i < 2; i++)
{
if (blastItemStacks[i].stackSize <= 0)
{
blastItemStacks[i] = new ItemStack(blastItemStacks[i].getItem().setFull3D());
}
else
{
blastItemStacks[i].stackSize--;
}
if (blastItemStacks[i].stackSize <= 0)
{
blastItemStacks[i] = null;
}
}
}
public int getItemBurnTime(ItemStack itemstack)
{
if (itemstack == null)
{
return 0;
}
int i = itemstack.getItem().itemID;
if (i < 256 && Block.blocksList[i].blockMaterial == Material.wood)
{
return 300;
}
if (i == Item.stick.itemID)
{
return 100;
}
if (i == Item.coal.itemID)
{
return 1600;
}
if (i == Item.bucketLava.itemID)
{
return 20000;
}
if (i == Item.blazeRod.itemID)
{
return 2400;
}
if (i == Block.sapling.blockID)
{
return 100;
}
else
{
return GameRegistry.getFuelValue(itemstack);
}
}
/**
* Do not make give this method the name canInteractWith because it clashes with Container
*/
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
if (worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) != this)
{
return false;
}
else
{
return entityplayer.getDistanceSq((double)xCoord + 0.5D, (double)yCoord + 0.5D, (double)zCoord + 0.5D) <= 64D;
}
}
/**
* Decrease the size of the stack in slot (first int arg) by the amount of the second int arg. Returns the new
* stack.
*/
public ItemStack decrStackSize(int i, int j)
{
if (blastItemStacks[i] != null)
{
if (blastItemStacks[i].stackSize <= j)
{
ItemStack itemstack = blastItemStacks[i];
blastItemStacks[i] = null;
return itemstack;
}
ItemStack itemstack1 = blastItemStacks[i].splitStack(j);
if (blastItemStacks[i].stackSize == 0)
{
blastItemStacks[i] = null;
}
return itemstack1;
}
else
{
return null;
}
}
/**
* Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
*/
public void setInventorySlotContents(int i, ItemStack itemstack)
{
blastItemStacks[i] = itemstack;
if (itemstack != null && itemstack.stackSize > getInventoryStackLimit())
{
itemstack.stackSize = getInventoryStackLimit();
}
}
/**
* Returns the name of the inventory.
*/
public String getInvName()
{
return "container.goldfurnace";
}
public void openChest()
{
}
public void closeChest()
{
}
/**
* When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem -
* like when you close a workbench GUI.
*/
public ItemStack getStackInSlotOnClosing(int i)
{
if (blastItemStacks[i] != null)
{
ItemStack itemstack = blastItemStacks[i];
blastItemStacks[i] = null;
return itemstack;
}
else
{
return null;
}
}
@Override
public boolean isInvNameLocalized()
{
return (this.customName != null) && (this.customName.length() > 0);
}
public void setCustomName(String name)
{
this.customName = name;
}
public void setGuiDisplayName(String displayName) {
// TODO Auto-generated method stub
public class ContainerAlembic extends Container
{
private TileEntityAlembic blast;
private int dualCookTime;
private int dualBurnTime;
private int lastItemBurnTime;
public ContainerAlembic(InventoryPlayer inventoryplayer, TileEntityAlembic tileentityAlembic)
{
dualCookTime = 0;
dualBurnTime = 0;
lastItemBurnTime = 0;
blast = tileentityAlembic;
this.addSlotToContainer(new Slot(tileentityAlembic, 0, 38, 17));
this.addSlotToContainer(new Slot(tileentityAlembic, 1, 74, 17));
this.addSlotToContainer(new Slot(tileentityAlembic, 2, 56, 53));
this.addSlotToContainer(new SlotAlembic(inventoryplayer.player, tileentityAlembic, 3, 116, 35));
for (int i = 0; i < 3; i++)
{
for (int k = 0; k < 9; k++)
{
this.addSlotToContainer(new Slot(inventoryplayer, k + i * 9 + 9, 8 + k * 18, 84 + i * 18));
}
}
for (int j = 0; j < 9; j++)
{
this.addSlotToContainer(new Slot(inventoryplayer, j, 8 + j * 18, 142));
}
}
public void addCraftingToCrafters(ICrafting par1ICrafting)
{
super.addCraftingToCrafters(par1ICrafting);
par1ICrafting.sendProgressBarUpdate(this, 0, this.blast.dualCookTime);
par1ICrafting.sendProgressBarUpdate(this, 1, this.blast.dualBurnTime);
par1ICrafting.sendProgressBarUpdate(this, 2, this.blast.currentItemBurnTime);
}
/**
* Looks for changes made in the container, sends them to every listener.
*/
public void detectAndSendChanges()
{
super.detectAndSendChanges();
for (int var1 = 0; var1 < this.crafters.size(); ++var1)
{
ICrafting var2 = (ICrafting)this.crafters.get(var1);
if (this.dualCookTime != this.blast.dualCookTime)
{
var2.sendProgressBarUpdate(this, 0, this.blast.dualCookTime);
}
if (this.dualBurnTime != this.blast.dualBurnTime)
{
var2.sendProgressBarUpdate(this, 1, this.blast.dualBurnTime);
}
if (this.lastItemBurnTime != this.blast.currentItemBurnTime)
{
var2.sendProgressBarUpdate(this, 2, this.blast.currentItemBurnTime);
}
}
this.dualCookTime = this.blast.dualCookTime;
this.dualBurnTime = this.blast.dualBurnTime;
this.lastItemBurnTime = this.blast.currentItemBurnTime;
}
public void updateProgressBar(int i, int j)
{
if (i == 0)
{
blast.dualCookTime = j;
}
if (i == 1)
{
blast.dualBurnTime = j;
}
if (i == 2)
{
blast.currentItemBurnTime = j;
}
}
/**
* Called to transfer a stack from one inventory to the other eg. when shift clicking.
*/
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2)
{
ItemStack itemstack = null;
Slot slot = (Slot)inventorySlots.get(par2);
if (slot != null && slot.getHasStack())
{
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
if (par2 == 2)
{
if (!mergeItemStack(itemstack1, 3, 39, true))
{
return null;
}
}
else if (par2 >= 3 && par2 < 30)
{
if (!mergeItemStack(itemstack1, 30, 39, false))
{
return null;
}
}
else if (par2 >= 30 && par2 < 39)
{
if (!mergeItemStack(itemstack1, 3, 30, false))
{
return null;
}
}
else if (!mergeItemStack(itemstack1, 3, 39, false))
{
return null;
}
if (itemstack1.stackSize == 0)
{
slot.putStack(null);
}
else
{
slot.onSlotChanged();
}
if (itemstack1.stackSize != itemstack.stackSize)
{
slot.onPickupFromSlot(par1EntityPlayer, itemstack1);
}
else
{
return null;
}
}
return itemstack;
}
public boolean canInteractWith(EntityPlayer entityplayer)
{
return blast.isUseableByPlayer(entityplayer);
}
}
Is there a way to make both blocks (as in the furnace) take up one ID? Like metadata?
Been away for a long time, back to basics. (Actually much more complicated) So does anyone know this? I think IC2 does it.
Just to rephrase the above, does anyone know how to store both of the tileentity states (on and off) in one Id?
Rollback Post to RevisionRollBack
Check out SpaceAge, a new futuristic themed mod on GitHub: Link
That's all my recipe class is at the moment. What method did that code go into?
Ok, I will. Thanks!
Yeah, so I'll get back to you after you read through the tutorial a couple times. That recipe class needs a lot of work.
For future reference, DON'T ever do this:
if (i == new ItemStack (Item.coal, 1, 1))
That is checking if the object 'i' which you got from an argument is equal to a NEW object you create on the spot; how could that possibly return true? Well, if it was a base type like int, but then you wouldn't be using 'new' would you? You could try:
if (i.equals(new ItemStack(Item.coal, 1, 1))
But even that is dodgy and could very easily give you unexpected results. Better to use:
if (i.itemID == Item.coal.itemID) or, in preparation for 1.7, something like if (i.getItem() == Item.coal) or comparing Item names or whatever.
Or for that matter the rest of your statement; when you have two distinct logic components, they must be isolated from each other by parentheses, so you can have:
if (a && { // do something }
if ((a && || (c && d)) { // do something }
Note that if all of your logic operators are the same, then the parentheses are unnecessary:
if (a && b && c && d) { }
if (a || b || c || d) { }
But as soon as you start mixing them up, you need to be very careful setting up your statement's logic scope (using parentheses) or it will probably do things very differently from what you expect.
Ok. All that code was based off the tutorial.
In my tile entity, it has this method (based off the tutorial):
Which brings you to the getSmeltingResult method.
The vanilla method is
Obviously mine needs to have the double input. This is what I have so far:
Which isn't working so I've done something wrong.
Whole Recipe class
Notice how you call 'Arrays.asList' twice, which should be giving you an error in your code. Remember that a HashMap key is a single object, be it an integer, a String, or in our case, a List of integers, so when you call the put method you used a single ArrayList correctly which creates the key, you need to use that same exact key when retrieving the object:
Oh thankyou! I was having the exact same problem for the longest time! Thanks again!
Find out how I generate....coolAlias...world structure generation and rotation tool...
Here is my recipe file:
Edit: Figured out my problem, it was in the tileentitiy.
Your tutorial is great!
I used another tutorial first and i used like 5 months on it. It never worked and i was not even half way!
When i found this tutorial and did it in 2 days!!!
I made it working but when i make two furnaces the first would not open the gui.
I copied the first furnace. I think its same ID in both of the furnaces thats why only the furnace dont work.
Where is the problem?
Usually it will be under your block class.
Look for a line this under your onBlockActivated method:
If you have been following Micro's tuts, it is most likely 0. Change that and you should be to go. Let me know how it comes out and don't forget to make sure it matches what you put for it in the GuiHandler!
Yup I figured it out! Thanks though!
BTW this is @Mattkx4......
I've played around a bit and only had the same problems as a best result, hopefully some help comes.
Towsty
TileEntityAlembic
import alchemycraft2.crafting.AlembicRecipes;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemPotion;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
public class TileEntityAlembic extends TileEntity implements IInventory
{
private ItemStack blastItemStacks[];
public int dualBurnTime;
public int currentItemBurnTime;
public int dualCookTime;
private String customName;
private static final int[] slots_top = new int[] {0, 1};
private static final int[] slots_bottom = new int[] {3};
private static final int[] slots_sides = new int[] {2};
public TileEntityAlembic()
{
blastItemStacks = new ItemStack[4];
dualBurnTime = 0;
currentItemBurnTime = 0;
dualCookTime = 0;
}
/**
* Returns the number of slots in the inventory.
*/
public int getSizeInventory()
{
return blastItemStacks.length;
}
/**
* Returns the stack in slot i
*/
public ItemStack getStackInSlot(int i)
{
return blastItemStacks[i];
}
public void setInventorySlotConatainers(int i, ItemStack itemstack)
{
blastItemStacks[i] = itemstack;
if (itemstack != null && itemstack.stackSize > getInventoryStackLimit())
{
itemstack.stackSize = getInventoryStackLimit();
}
}
/**
* Reads a tile entity from NBT.
*/
public void readFromNBT(NBTTagCompound nbttagcompound)
{
super.readFromNBT(nbttagcompound);
NBTTagList nbttaglist = nbttagcompound.getTagList("Items");
blastItemStacks = new ItemStack[getSizeInventory()];
for (int i = 0; i < nbttaglist.tagCount(); i++)
{
NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i);
byte byte0 = nbttagcompound1.getByte("Slot");
if (byte0 >= 0 && byte0 < blastItemStacks.length)
{
blastItemStacks[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
}
}
dualBurnTime = nbttagcompound.getShort("BurnTime");
dualCookTime = nbttagcompound.getShort("CookTime");
currentItemBurnTime = getItemBurnTime(blastItemStacks[1]);
}
/**
* Writes a tile entity to NBT.
*/
public void writeToNBT(NBTTagCompound nbttagcompound)
{
super.writeToNBT(nbttagcompound);
nbttagcompound.setShort("BurnTime", (short)dualBurnTime);
nbttagcompound.setShort("CookTime", (short)dualCookTime);
NBTTagList nbttaglist = new NBTTagList();
for (int i = 0; i < blastItemStacks.length; i++)
{
if (blastItemStacks[i] != null)
{
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
nbttagcompound1.setByte("Slot", (byte)i);
blastItemStacks[i].writeToNBT(nbttagcompound1);
nbttaglist.appendTag(nbttagcompound1);
}
}
nbttagcompound.setTag("Items", nbttaglist);
}
/**
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't
* this more of a set than a get?*
*/
public int getInventoryStackLimit()
{
return 64;
}
public int getCookProgressScaled(int i)
{
return (dualCookTime * i) / 200;
}
public int getBurnTimeRemainingScaled(int i)
{
if (currentItemBurnTime == 0)
{
currentItemBurnTime = 200;
}
return (dualBurnTime * i) / currentItemBurnTime;
}
public boolean isBurning()
{
return dualBurnTime > 0;
}
/**
* Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count
* ticks and creates a new spawn inside its implementation.
*/
public void updateEntity()
{
boolean flag = dualBurnTime > 0;
boolean flag1 = false;
if (dualBurnTime > 0)
{
dualBurnTime--;
}
if (!worldObj.isRemote)
{
if (dualBurnTime == 0 && canSmelt())
{
currentItemBurnTime = dualBurnTime = getItemBurnTime(blastItemStacks[2]);
if (dualBurnTime > 0)
{
flag1 = true;
if (blastItemStacks[2] != null)
{
if (blastItemStacks[2].stackSize == 0)
{
blastItemStacks[2] = new ItemStack(blastItemStacks[2].getItem().setFull3D());
}
else
{
blastItemStacks[2].stackSize--;
}
if (blastItemStacks[2].stackSize == 0)
{
blastItemStacks[2] = null;
}
}
}
}
if (isBurning() && canSmelt())
{
dualCookTime++;
if (dualCookTime == 200)
{
dualCookTime = 0;
smeltItem();
flag1 = true;
}
}
else
{
dualCookTime = 0;
}
if (flag != (dualBurnTime > 0))
{
flag1 = true;
}
}
if (flag1)
{
onInventoryChanged();
}
}
private boolean canSmelt()
{
if (blastItemStacks[0] == null || blastItemStacks[1] == null)
{
return false;
}
ItemStack itemstack = AlembicRecipes.getSmeltingResult(blastItemStacks[0].getItem().itemID, blastItemStacks[1].getItem().itemID);
if (itemstack == null)
{
return false;
}
if (blastItemStacks[3] == null)
{
return true;
}
if (!blastItemStacks[3].isItemEqual(itemstack))
{
return false;
}
if (blastItemStacks[3].stackSize < getInventoryStackLimit() && blastItemStacks[3].stackSize < blastItemStacks[3].getMaxStackSize())
{
return true;
}
else
{
return blastItemStacks[3].stackSize < itemstack.getMaxStackSize();
}
}
public void smeltItem()
{
if (!canSmelt())
{
return;
}
ItemStack itemstack = AlembicRecipes.getSmeltingResult(blastItemStacks[0].getItem().itemID, blastItemStacks[1].getItem().itemID);
if (blastItemStacks[3] == null)
{
blastItemStacks[3] = itemstack.copy();
}
else if (blastItemStacks[3].itemID == itemstack.itemID)
{
blastItemStacks[3].stackSize++;
}
for (int i = 0; i < 2; i++)
{
if (blastItemStacks[i].stackSize <= 0)
{
blastItemStacks[i] = new ItemStack(blastItemStacks[i].getItem().setFull3D());
}
else
{
blastItemStacks[i].stackSize--;
}
if (blastItemStacks[i].stackSize <= 0)
{
blastItemStacks[i] = null;
}
}
}
public int getItemBurnTime(ItemStack itemstack)
{
if (itemstack == null)
{
return 0;
}
int i = itemstack.getItem().itemID;
if (i < 256 && Block.blocksList[i].blockMaterial == Material.wood)
{
return 300;
}
if (i == Item.stick.itemID)
{
return 100;
}
if (i == Item.coal.itemID)
{
return 1600;
}
if (i == Item.bucketLava.itemID)
{
return 20000;
}
if (i == Item.blazeRod.itemID)
{
return 2400;
}
if (i == Block.sapling.blockID)
{
return 100;
}
else
{
return GameRegistry.getFuelValue(itemstack);
}
}
/**
* Do not make give this method the name canInteractWith because it clashes with Container
*/
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
if (worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) != this)
{
return false;
}
else
{
return entityplayer.getDistanceSq((double)xCoord + 0.5D, (double)yCoord + 0.5D, (double)zCoord + 0.5D) <= 64D;
}
}
/**
* Decrease the size of the stack in slot (first int arg) by the amount of the second int arg. Returns the new
* stack.
*/
public ItemStack decrStackSize(int i, int j)
{
if (blastItemStacks[i] != null)
{
if (blastItemStacks[i].stackSize <= j)
{
ItemStack itemstack = blastItemStacks[i];
blastItemStacks[i] = null;
return itemstack;
}
ItemStack itemstack1 = blastItemStacks[i].splitStack(j);
if (blastItemStacks[i].stackSize == 0)
{
blastItemStacks[i] = null;
}
return itemstack1;
}
else
{
return null;
}
}
/**
* Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
*/
public void setInventorySlotContents(int i, ItemStack itemstack)
{
blastItemStacks[i] = itemstack;
if (itemstack != null && itemstack.stackSize > getInventoryStackLimit())
{
itemstack.stackSize = getInventoryStackLimit();
}
}
/**
* Returns the name of the inventory.
*/
public String getInvName()
{
return "container.goldfurnace";
}
public void openChest()
{
}
public void closeChest()
{
}
/**
* When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem -
* like when you close a workbench GUI.
*/
public ItemStack getStackInSlotOnClosing(int i)
{
if (blastItemStacks[i] != null)
{
ItemStack itemstack = blastItemStacks[i];
blastItemStacks[i] = null;
return itemstack;
}
else
{
return null;
}
}
@Override
public boolean isInvNameLocalized()
{
return (this.customName != null) && (this.customName.length() > 0);
}
public void setCustomName(String name)
{
this.customName = name;
}
public void setGuiDisplayName(String displayName) {
// TODO Auto-generated method stub
}
@Override
public boolean isItemValidForSlot(int par1, ItemStack par2ItemStack)
{
return par1 == 3 || getItemBurnTime(par2ItemStack) <= 0 ? false : true;
}
public int[] getAccessibleSlotsFromSide(int par1)
{
return par1 == 0 || par1 == 1 ? slots_top : slots_sides;
}
public boolean canInsertItem(int par1, ItemStack par2ItemStack, int par3)
{
return this.isItemValidForSlot(par1, par2ItemStack);
}
public boolean canExtractItem(int par1, ItemStack par2ItemStack, int par3)
{
return par1 == 3 ? true : false;
}
}
ContainerAlembic
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public class ContainerAlembic extends Container
{
private TileEntityAlembic blast;
private int dualCookTime;
private int dualBurnTime;
private int lastItemBurnTime;
public ContainerAlembic(InventoryPlayer inventoryplayer, TileEntityAlembic tileentityAlembic)
{
dualCookTime = 0;
dualBurnTime = 0;
lastItemBurnTime = 0;
blast = tileentityAlembic;
this.addSlotToContainer(new Slot(tileentityAlembic, 0, 38, 17));
this.addSlotToContainer(new Slot(tileentityAlembic, 1, 74, 17));
this.addSlotToContainer(new Slot(tileentityAlembic, 2, 56, 53));
this.addSlotToContainer(new SlotAlembic(inventoryplayer.player, tileentityAlembic, 3, 116, 35));
for (int i = 0; i < 3; i++)
{
for (int k = 0; k < 9; k++)
{
this.addSlotToContainer(new Slot(inventoryplayer, k + i * 9 + 9, 8 + k * 18, 84 + i * 18));
}
}
for (int j = 0; j < 9; j++)
{
this.addSlotToContainer(new Slot(inventoryplayer, j, 8 + j * 18, 142));
}
}
public void addCraftingToCrafters(ICrafting par1ICrafting)
{
super.addCraftingToCrafters(par1ICrafting);
par1ICrafting.sendProgressBarUpdate(this, 0, this.blast.dualCookTime);
par1ICrafting.sendProgressBarUpdate(this, 1, this.blast.dualBurnTime);
par1ICrafting.sendProgressBarUpdate(this, 2, this.blast.currentItemBurnTime);
}
/**
* Looks for changes made in the container, sends them to every listener.
*/
public void detectAndSendChanges()
{
super.detectAndSendChanges();
for (int var1 = 0; var1 < this.crafters.size(); ++var1)
{
ICrafting var2 = (ICrafting)this.crafters.get(var1);
if (this.dualCookTime != this.blast.dualCookTime)
{
var2.sendProgressBarUpdate(this, 0, this.blast.dualCookTime);
}
if (this.dualBurnTime != this.blast.dualBurnTime)
{
var2.sendProgressBarUpdate(this, 1, this.blast.dualBurnTime);
}
if (this.lastItemBurnTime != this.blast.currentItemBurnTime)
{
var2.sendProgressBarUpdate(this, 2, this.blast.currentItemBurnTime);
}
}
this.dualCookTime = this.blast.dualCookTime;
this.dualBurnTime = this.blast.dualBurnTime;
this.lastItemBurnTime = this.blast.currentItemBurnTime;
}
public void updateProgressBar(int i, int j)
{
if (i == 0)
{
blast.dualCookTime = j;
}
if (i == 1)
{
blast.dualBurnTime = j;
}
if (i == 2)
{
blast.currentItemBurnTime = j;
}
}
/**
* Called to transfer a stack from one inventory to the other eg. when shift clicking.
*/
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2)
{
ItemStack itemstack = null;
Slot slot = (Slot)inventorySlots.get(par2);
if (slot != null && slot.getHasStack())
{
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
if (par2 == 2)
{
if (!mergeItemStack(itemstack1, 3, 39, true))
{
return null;
}
}
else if (par2 >= 3 && par2 < 30)
{
if (!mergeItemStack(itemstack1, 30, 39, false))
{
return null;
}
}
else if (par2 >= 30 && par2 < 39)
{
if (!mergeItemStack(itemstack1, 3, 30, false))
{
return null;
}
}
else if (!mergeItemStack(itemstack1, 3, 39, false))
{
return null;
}
if (itemstack1.stackSize == 0)
{
slot.putStack(null);
}
else
{
slot.onSlotChanged();
}
if (itemstack1.stackSize != itemstack.stackSize)
{
slot.onPickupFromSlot(par1EntityPlayer, itemstack1);
}
else
{
return null;
}
}
return itemstack;
}
public boolean canInteractWith(EntityPlayer entityplayer)
{
return blast.isUseableByPlayer(entityplayer);
}
}
Been away for a long time, back to basics. (Actually much more complicated) So does anyone know this? I think IC2 does it.
Just to rephrase the above, does anyone know how to store both of the tileentity states (on and off) in one Id?