How would I have to change the recipe format if I wanted say a dual output furnace? For example if I wanted two items to be smelted from one item. Also would it be the same for a crafting table? like if I wanted to make a crafting table that gave two different items from a single recipe?
How would I have to change the recipe format if I wanted say a dual output furnace? For example if I wanted two items to be smelted from one item. Also would it be the same for a crafting table? like if I wanted to make a crafting table that gave two different items from a single recipe?
To get multiple outputs, you wouldn't be able to use a single HashMap
But you could use 2, one for each output and put the input itemID as the key with the output itemID as the result. Then when you call smeltItem() from your furnace, have it check both maps and if the output of map1 is not null, place it in output slot 1, if map2 result is not null, place in output slot 2, etc. for as many outputs as you want.
If you're not comfortable with HashMaps, just hand-code the methods:
// in your Recipes class
public ItemStack getSmeltResultOne(ItemStack itemstack)
{
ItemStack result = null;
if (itemstack.itemID == YourMod.yourItem.itemID)
result = new ItemStack(Item.ingotIron.itemID, 4);
return result;
}
public ItemStack getSmeltResultTwo(ItemStack itemstack)
{
ItemStack result = null;
if (itemstack.itemID == YourMod.yourItem.itemID)
result = new ItemStack(Item.diamond.itemID);
return result;
}
To get multiple outputs, you wouldn't be able to use a single HashMap
But you could use 2, one for each output and put the input itemID as the key with the output itemID as the result. Then when you call smeltItem() from your furnace, have it check both maps and if the output of map1 is not null, place it in output slot 1, if map2 result is not null, place in output slot 2, etc. for as many outputs as you want.
If you're not comfortable with HashMaps, just hand-code the methods:
// in your Recipes class
public ItemStack getSmeltResultOne(ItemStack itemstack)
{
ItemStack result = null;
if (itemstack.itemID == YourMod.yourItem.itemID)
result = new ItemStack(Item.ingotIron.itemID, 4);
return result;
}
public ItemStack getSmeltResultTwo(ItemStack itemstack)
{
ItemStack result = null;
if (itemstack.itemID == YourMod.yourItem.itemID)
result = new ItemStack(Item.diamond.itemID);
return result;
}
To get multiple outputs, you wouldn't be able to use a single HashMap
Okay he has the idea, he should be able to figure it out if he can figure out how normal recipes work.
Anyways coolAlias, wouldn't a single hash do the trick if it mapped not to a item stack but a ItemStack[] containing two items?
Okay he has the idea, he should be able to figure it out if he can figure out how normal recipes work.
Anyways coolAlias, wouldn't a single hash do the trick if it mapped not to a item stack but a ItemStack[] containing two items?
I was thinking the same thing, or similar. Looking at the way the two input furnace works with the custom recipes like I have them, I was thinking that he could use the tile to handle the two out puts and adjust the container so it has two out put slots. Then in the custom recipe class it would be like I have now, just with two out puts as opposed to two in....but as I have not done this actually, thought about it though, that is the way I was thinking even though it sounds easier than it probably really is...
I was thinking the same thing, or similar. Looking at the way the two input furnace works with the custom recipes like I have them, I was thinking that he could use the tile to handle the two out puts and adjust the container so it has two out put slots. Then in the custom recipe class it would be like I have now, just with two out puts as opposed to two in....but as I have not done this actually, thought about it though, that is the way I was thinking even though it sounds easier than it probably really is...
I'm going to try it this way when I get home tonight. My thought was that I would run into an issue of only being able to retrieve one of the outputs and cause the other to disappear, but maybe not. I will test it and see.
Okay he has the idea, he should be able to figure it out if he can figure out how normal recipes work.
Anyways coolAlias, wouldn't a single hash do the trick if it mapped not to a item stack but a ItemStack[] containing two items?
Lol indeed you could. Sorry I wasn't thinking straight on that one I was still thinking of the time I tried to use ItemStacks as a key in my HashMap and it didn't work out very well... but of course you could return an ItemStack array.
See this for what I mean about using ItemStack as a key.
How do you mean...link?Do you mean the texture? or when you activate the block and the gui opens? For the first just design your texture in your favorite pic editor and then use it in the code for the GUI class. For the latter, just use the GUI handler like any other GUI block....for example look at first post. I did this because this was a basic follow along set up so you could see from one furnace type to the next following the first one....
hey do you know for the duel furnace how do you link the gui with the block because it does not show you
If you read the info at the beginning of micros post you will see that he only posted the code that has changed from his first example. All the other classes you will get from the first furnace.
for the duel input furnace could you add the block and mod class because I do not know what I need to but in my mod class and block class
Please do like you are being asked to do. All the information is here on this thread as MCDigger had pointed out. Go to the first page and at the top is all the information you need. For the other tutorials, I only posted the class files that have changed depending upon the tutorial. So, for the block, mod class, and anything else like the GUI handler...these will all be in the first post.
public class BlockBioFurnace extends BlockContainer
{
private Random bioRand = new Random();
private final boolean isActive;
private static boolean keepBioInventory = false;
public int idDropped(int par1, Random par2Random, int par3)
{
return BioFurnace.bioFurnaceOff.blockID;
}
public void onBlockAdded(World par1World, int par2, int par3, int par4)
{
super.onBlockAdded(par1World, par2, par3, par4);
this.setDefaultDirection(par1World, par2, par3, par4);
}
private void setDefaultDirection(World par1World, int par2, int par3, int par4)
{
if (!par1World.isRemote)
{
int l = par1World.getBlockId(par2, par3, par4 - 1);
int i1 = par1World.getBlockId(par2, par3, par4 + 1);
int j1 = par1World.getBlockId(par2 - 1, par3, par4);
int k1 = par1World.getBlockId(par2 + 1, par3, par4);
byte b0 = 3;
if (Block.opaqueCubeLookup[l] && !Block.opaqueCubeLookup[i1])
{
b0 = 3;
}
if (Block.opaqueCubeLookup[i1] && !Block.opaqueCubeLookup[l])
{
b0 = 2;
}
if (Block.opaqueCubeLookup[j1] && !Block.opaqueCubeLookup[k1])
{
b0 = 5;
}
if (Block.opaqueCubeLookup[k1] && !Block.opaqueCubeLookup[j1])
{
b0 = 4;
}
par1World.setBlockMetadataWithNotify(par2, par3, par4, b0, 2);
}
}
public TileEntity createNewTileEntity(World par1World)
{
return new TileEntityBioFurnace();
}
public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLivingBase par5EntityLivingBase, ItemStack par6ItemStack)
{
int l = MathHelper.floor_double((double)(par5EntityLivingBase.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
if (l == 0)
{
par1World.setBlockMetadataWithNotify(par2, par3, par4, 2, 2);
}
if (l == 1)
{
par1World.setBlockMetadataWithNotify(par2, par3, par4, 5, 2);
}
if (l == 2)
{
par1World.setBlockMetadataWithNotify(par2, par3, par4, 3, 2);
}
if (l == 3)
{
par1World.setBlockMetadataWithNotify(par2, par3, par4, 4, 2);
}
if (par6ItemStack.hasDisplayName())
{
((TileEntityBioFurnace)par1World.getBlockTileEntity(par2, par3, par4)).setCustomName(par6ItemStack.getDisplayName());
}
}
public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
{
if (!keepBioInventory)
{
TileEntityBioFurnace var7 = (TileEntityBioFurnace)par1World.getBlockTileEntity(par2, par3, par4);
if (var7 != null)
{
for (int var8 = 0; var8 < var7.getSizeInventory(); ++var8)
{
ItemStack itemstack = var7.getStackInSlot(var8);
if (itemstack != null)
{
float f = this.bioRand.nextFloat() * 0.8F + 0.1F;
float f1 = this.bioRand.nextFloat() * 0.8F + 0.1F;
float f2 = this.bioRand.nextFloat() * 0.8F + 0.1F;
while (itemstack.stackSize > 0)
{
int k1 = this.bioRand.nextInt(21) + 10;
if (k1 > itemstack.stackSize)
{
k1 = itemstack.stackSize;
}
itemstack.stackSize -= k1;
EntityItem entityitem = new EntityItem(par1World, (double)((float)par2 + f), (double)((float)par3 + f1), (double)((float)par4 + f2), new ItemStack(itemstack.itemID, k1, itemstack.getItemDamage()));
if (itemstack.hasTagCompound())
{
entityitem.getEntityItem().setTagCompound((NBTTagCompound)itemstack.getTagCompound().copy());
}
float f3 = 0.05F;
entityitem.motionX = (double)((float)this.bioRand.nextGaussian() * f3);
entityitem.motionY = (double)((float)this.bioRand.nextGaussian() * f3 + 0.2F);
entityitem.motionZ = (double)((float)this.bioRand.nextGaussian() * f3);
par1World.spawnEntityInWorld(entityitem);
}
}
}
par1World.func_96440_m(par2, par3, par4, par5);
}
}
super.breakBlock(par1World, par2, par3, par4, par5, par6);
}
public boolean hasComparatorInputOverride()
{
return true;
}
public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5)
{
return Container.calcRedstoneFromInventory((IInventory)par1World.getBlockTileEntity(par2, par3, par4));
}
}
and also I feel like I have to make a Render class but it doesn't anything on making one in the tutorial.
See my post here for an alternative to shadowbeast007's way of getting the front side of your furnace to render correctly in the inventory.
The easiest way involves a base edit; the hard way does involve creating a custom Render class that extends RenderBlocks.
Yeah, the way Shadow did it was just a copy of the render code in the render class (vanilla code) and tweaked it a bit. Some how he can see it in his head how some code works and getting him to explain well is not easy. He is kind of advanced in some ways, does great work with making custom mobs...check out the fossil mod revival he has done all the dino work there and made vast improvements over the original mod.
Hey microjunk. I have been pumping out these different furnaces pretty good now and I am building my own furnace upgrade system for my mod, but I have hit a roadblock. I am trying to code out a double dual input furnace by combining the code from your two examples and have thus far been unsuccessful. My latest attempt's results have been ..a bit wacky lol. If I put items in the first set of inputs, it smelted just fine. If I put items in the second set, it wouldn't smelt, however if I put an item in the second set while the first set was smelting, then the fuel slot would rapidly deplete it's fuel within seconds lol.
I have tried multiple variations of my code and I can just not seem to get the results I am looking for. I am sure I probably have mistakes in both my TileEntity class and the FurnaceStack class. I think the combination of these two furnace types is confusing me and I am getting to the point where I just need some help. If you or even anyone else could take a look at my code if you get the time and help me out or at least tell me what I am doing wrong, that would be awesome! This is becoming a lot more complicated than I had thought it would be. Anyway, here are my classes.
if (block == Block.woodSingleSlab)
{
return 150;
}
if (block.blockMaterial == Material.wood)
{
return 300;
}
}
//THis is where you would add any items you want to be used as fuel. The return value is the burn length.
if (item instanceof ItemTool && ((ItemTool) item).getToolMaterialName().equals("WOOD")) return 200;
if (item instanceof ItemSword && ((ItemSword) item).getToolMaterialName().equals("WOOD")) return 200;
if (item instanceof ItemHoe && ((ItemHoe) item).getMaterialName().equals("WOOD")) return 200;
if (i == Item.stick.itemID) return 100;
if (i == Item.coal.itemID) return 1600;
if (i == Item.bucketLava.itemID) return 20000;
if (i == Block.sapling.blockID) return 100;
if (i == Item.blazeRod.itemID) return 2400;
if (i == Item.rottenFlesh.itemID) return 400;
if (i == BigModMain.BucketOil.itemID) return 12000;
if (i == BigModMain.RawOil.itemID) return 2000;
if (i == BigModMain.CokeChunk.itemID) return 400;
return GameRegistry.getFuelValue(par0ItemStack);
}
}
/**
* 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 "Forge";
}
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 isStackValidForSlot(int i, ItemStack itemstack) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onInventoryChanged() {
// TODO Auto-generated method stub
public class ContainerForgeGrayBrick extends Container
{
private TileEntityForgeGrayBrick blast;
private int dualBurnTime;
private int dualCookTime1;
private int dualCookTime2;
private int lastItemBurnTime;
public ContainerForgeGrayBrick(InventoryPlayer inventoryplayer, TileEntityForgeGrayBrick tileEntity)
{
dualCookTime1 = 0;
dualCookTime2 = 0;
dualBurnTime = 0;
lastItemBurnTime = 0;
blast = tileEntity;
this.addSlotToContainer(new Slot(tileEntity, 0, 42, 17)); //First Input 1
this.addSlotToContainer(new Slot(tileEntity, 1, 70, 17)); //Second Input 1
this.addSlotToContainer(new Slot(tileEntity, 2, 17, 33)); //Fuel
this.addSlotToContainer(new SlotForge(inventoryplayer.player, tileEntity, 3, 116, 17)); //Output 1
this.addSlotToContainer(new Slot(tileEntity, 4, 42, 35)); //First Input 2
this.addSlotToContainer(new Slot(tileEntity, 5, 70, 35)); //Second Input 2
this.addSlotToContainer(new SlotForge(inventoryplayer.player, tileEntity, 6, 116, 35)); //Output 2
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.dualCookTime1);
par1ICrafting.sendProgressBarUpdate(this, 1, this.blast.dualBurnTime);
par1ICrafting.sendProgressBarUpdate(this, 2, this.blast.currentItemBurnTime);
par1ICrafting.sendProgressBarUpdate(this, 4, this.blast.dualCookTime2);
}
/**
* 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.dualCookTime1 != this.blast.dualCookTime1)
{
var2.sendProgressBarUpdate(this, 0, this.blast.dualCookTime1);
}
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);
}
if (this.dualCookTime2 != this.blast.dualCookTime2)
{
var2.sendProgressBarUpdate(this, 0, this.blast.dualCookTime2);
}
}
this.dualCookTime1 = this.blast.dualCookTime1;
this.dualCookTime2 = this.blast.dualCookTime2;
this.dualBurnTime = this.blast.dualBurnTime;
this.lastItemBurnTime = this.blast.currentItemBurnTime;
}
public void updateProgressBar(int i, int j)
{
if (i == 0)
{
blast.dualCookTime1 = j;
}
if (i == 1)
{
blast.dualBurnTime = j;
}
if (i == 2)
{
blast.currentItemBurnTime = j;
}
if (i == 4)
{
blast.dualCookTime2 = 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);
}
}
Hey microjunk. I have been pumping out these different furnaces pretty good now and I am building my own furnace upgrade system for my mod, but I have hit a roadblock. I am trying to code out a double dual input furnace by combining the code from your two examples and have thus far been unsuccessful. My latest attempt's results have been ..a bit wacky lol. If I put items in the first set of inputs, it smelted just fine. If I put items in the second set, it wouldn't smelt, however if I put an item in the second set while the first set was smelting, then the fuel slot would rapidly deplete it's fuel within seconds lol.
I have tried multiple variations of my code and I can just not seem to get the results I am looking for. I am sure I probably have mistakes in both my TileEntity class and the FurnaceStack class. I think the combination of these two furnace types is confusing me and I am getting to the point where I just need some help. If you or even anyone else could take a look at my code if you get the time and help me out or at least tell me what I am doing wrong, that would be awesome! This is becoming a lot more complicated than I had thought it would be. Anyway, here are my classes.
Okay....thanks for being efficient first of all....Take a look at my double furnace code. You will see that it has two inputs and two outputs. If you look into the tile entity there you will see that it is doubled up on everything but the fuel source. So taking that as an example, in your tile you will need to make the code reflect how that one works, having four inputs and two outputs using two fuel sources. So they only thing you really need to add is for the two more ins and one more out and one more fuel slot. If you read carefully through the code you can begin to see how these are implemented and should be able to add those in. You shouldn't need to change anything in the furnace stack code, however you will need to adjust the container in the crafters method and the detect and save method. I dont have the code in front of me right now, I was actually getting ready for bed (24 hours now and counting), but I will look at it tomorrow and see if I can mock something up to help.
Please forgive me I have been real busy lately recoding my structures in my mod for the use of a new tool for generation by coolAlias and is taking a considerable amount of time (78 structures).
Okay....thanks for being efficient first of all....Take a look at my double furnace code. You will see that it has two inputs and two outputs. If you look into the tile entity there you will see that it is doubled up on everything but the fuel source. So taking that as an example, in your tile you will need to make the code reflect how that one works, having four inputs and two outputs using two fuel sources. So they only thing you really need to add is for the two more ins and one more out and one more fuel slot. If you read carefully through the code you can begin to see how these are implemented and should be able to add those in. You shouldn't need to change anything in the furnace stack code, however you will need to adjust the container in the crafters method and the detect and save method. I dont have the code in front of me right now, I was actually getting ready for bed (24 hours now and counting), but I will look at it tomorrow and see if I can mock something up to help.
Please forgive me I have been real busy lately recoding my structures in my mod for the use of a new tool for generation by coolAlias and is taking a considerable amount of time (78 structures).
No worries man. I definitely understand being busy and if you do happen to get a chance to look at it, any help would be appreciated for sure, but for now I will take what you told me and keep working at it. I will post a reply if I happen to get it working so you know not to worry about it. Thanks micro!
To get multiple outputs, you wouldn't be able to use a single HashMap
But you could use 2, one for each output and put the input itemID as the key with the output itemID as the result. Then when you call smeltItem() from your furnace, have it check both maps and if the output of map1 is not null, place it in output slot 1, if map2 result is not null, place in output slot 2, etc. for as many outputs as you want.
If you're not comfortable with HashMaps, just hand-code the methods:
Something like that.
Ill give this a go and see if I can figure it out
Okay he has the idea, he should be able to figure it out if he can figure out how normal recipes work.
Anyways coolAlias, wouldn't a single hash do the trick if it mapped not to a item stack but a ItemStack[] containing two items?
I was thinking the same thing, or similar. Looking at the way the two input furnace works with the custom recipes like I have them, I was thinking that he could use the tile to handle the two out puts and adjust the container so it has two out put slots. Then in the custom recipe class it would be like I have now, just with two out puts as opposed to two in....but as I have not done this actually, thought about it though, that is the way I was thinking even though it sounds easier than it probably really is...
Find out how I generate....coolAlias...world structure generation and rotation tool...
I'm going to try it this way when I get home tonight. My thought was that I would run into an issue of only being able to retrieve one of the outputs and cause the other to disappear, but maybe not. I will test it and see.
Lol indeed you could. Sorry I wasn't thinking straight on that one I was still thinking of the time I tried to use ItemStacks as a key in my HashMap and it didn't work out very well... but of course you could return an ItemStack array.
See this for what I mean about using ItemStack as a key.
Find out how I generate....coolAlias...world structure generation and rotation tool...
Find out how I generate....coolAlias...world structure generation and rotation tool...
If you read the info at the beginning of micros post you will see that he only posted the code that has changed from his first example. All the other classes you will get from the first furnace.
Take a look at the first furnace tut for that.
Please do like you are being asked to do. All the information is here on this thread as MCDigger had pointed out. Go to the first page and at the top is all the information you need. For the other tutorials, I only posted the class files that have changed depending upon the tutorial. So, for the block, mod class, and anything else like the GUI handler...these will all be in the first post.
Find out how I generate....coolAlias...world structure generation and rotation tool...
One being the Block class doesn't like the .setCustomName at all.
Block class...
import java.util.Random;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
public class BlockBioFurnace extends BlockContainer
{
private Random bioRand = new Random();
private final boolean isActive;
private static boolean keepBioInventory = false;
@SideOnly(Side.CLIENT)
private Icon furnaceIconTop;
@SideOnly(Side.CLIENT)
private Icon furnaceIconFront;
public BlockBioFurnace(int par1, boolean par2)
{
super(par1, Material.rock);
this.isActive = par2;
}
public int getRenderType()
{
return 2105;
}
public int idDropped(int par1, Random par2Random, int par3)
{
return BioFurnace.bioFurnaceOff.blockID;
}
public void onBlockAdded(World par1World, int par2, int par3, int par4)
{
super.onBlockAdded(par1World, par2, par3, par4);
this.setDefaultDirection(par1World, par2, par3, par4);
}
private void setDefaultDirection(World par1World, int par2, int par3, int par4)
{
if (!par1World.isRemote)
{
int l = par1World.getBlockId(par2, par3, par4 - 1);
int i1 = par1World.getBlockId(par2, par3, par4 + 1);
int j1 = par1World.getBlockId(par2 - 1, par3, par4);
int k1 = par1World.getBlockId(par2 + 1, par3, par4);
byte b0 = 3;
if (Block.opaqueCubeLookup[l] && !Block.opaqueCubeLookup[i1])
{
b0 = 3;
}
if (Block.opaqueCubeLookup[i1] && !Block.opaqueCubeLookup[l])
{
b0 = 2;
}
if (Block.opaqueCubeLookup[j1] && !Block.opaqueCubeLookup[k1])
{
b0 = 5;
}
if (Block.opaqueCubeLookup[k1] && !Block.opaqueCubeLookup[j1])
{
b0 = 4;
}
par1World.setBlockMetadataWithNotify(par2, par3, par4, b0, 2);
}
}
@SideOnly(Side.CLIENT)
public Icon getIcon(int par1, int par2)
{
return par1 == 1 ? this.furnaceIconTop : (par1 == 0 ? this.furnaceIconTop : (par1 != par2 ? this.blockIcon : this.furnaceIconFront));
}
@SideOnly(Side.CLIENT)
public void registerIcons(IconRegister par1IconRegister)
{
this.blockIcon = par1IconRegister.registerIcon("HighSpeed:extruderBack");
this.furnaceIconFront = par1IconRegister.registerIcon(this.isActive ? "HighSpeed:extruderActive" : "HighSpeed:extruderIdle");
this.furnaceIconTop = par1IconRegister.registerIcon("HighSpeed:extruderTop");
}
@SideOnly(Side.CLIENT)
public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random)
{
if (this.isActive)
{
int var6 = par1World.getBlockMetadata(par2, par3, par4);
float var7 = (float)par2 + 0.5F;
float var8 = (float)par3 + 0.0F + par5Random.nextFloat() * 6.0F / 16.0F;
float var9 = (float)par4 + 0.5F;
float var10 = 0.52F;
float var11 = par5Random.nextFloat() * 0.6F - 0.3F;
if (var6 == 4)
{
par1World.spawnParticle("smoke", (double)(var7 - var10), (double)var8, (double)(var9 + var11), 0.0D, 0.0D, 0.0D);
par1World.spawnParticle("flame", (double)(var7 - var10), (double)var8, (double)(var9 + var11), 0.0D, 0.0D, 0.0D);
}
else if (var6 == 5)
{
par1World.spawnParticle("smoke", (double)(var7 + var10), (double)var8, (double)(var9 + var11), 0.0D, 0.0D, 0.0D);
par1World.spawnParticle("flame", (double)(var7 + var10), (double)var8, (double)(var9 + var11), 0.0D, 0.0D, 0.0D);
}
else if (var6 == 2)
{
par1World.spawnParticle("smoke", (double)(var7 + var11), (double)var8, (double)(var9 - var10), 0.0D, 0.0D, 0.0D);
par1World.spawnParticle("flame", (double)(var7 + var11), (double)var8, (double)(var9 - var10), 0.0D, 0.0D, 0.0D);
}
else if (var6 == 3)
{
par1World.spawnParticle("smoke", (double)(var7 + var11), (double)var8, (double)(var9 + var10), 0.0D, 0.0D, 0.0D);
par1World.spawnParticle("flame", (double)(var7 + var11), (double)var8, (double)(var9 + var10), 0.0D, 0.0D, 0.0D);
}
}
}
public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
{
if (par1World.isRemote)
{
return true;
}
else if (!par5EntityPlayer.isSneaking())
{
TileEntityBioFurnace var10 = (TileEntityBioFurnace) par1World.getBlockTileEntity(par2, par3, par4);
if (var10 != null)
{
par5EntityPlayer.openGui(BioFurnace.instance, 0, par1World, par2, par3, par4);
}
return true;
}
else
{
return false;
}
}
public static void updateFurnaceBlockState(boolean par0, World par1World, int par2, int par3, int par4)
{
int var5 = par1World.getBlockMetadata(par2, par3, par4);
TileEntity var6 = par1World.getBlockTileEntity(par2, par3, par4);
keepBioInventory = true;
if (par0)
{
par1World.setBlock(par2, par3, par4, BioFurnace.bioFurnaceOn.blockID);
}
else
{
par1World.setBlock(par2, par3, par4, BioFurnace.bioFurnaceOff.blockID);
}
keepBioInventory = false;
par1World.setBlockMetadataWithNotify(par2, par3, par4, var5, 2);
if (var6 != null)
{
var6.validate();
par1World.setBlockTileEntity(par2, par3, par4, var6);
}
}
public TileEntity createNewTileEntity(World par1World)
{
return new TileEntityBioFurnace();
}
public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLivingBase par5EntityLivingBase, ItemStack par6ItemStack)
{
int l = MathHelper.floor_double((double)(par5EntityLivingBase.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
if (l == 0)
{
par1World.setBlockMetadataWithNotify(par2, par3, par4, 2, 2);
}
if (l == 1)
{
par1World.setBlockMetadataWithNotify(par2, par3, par4, 5, 2);
}
if (l == 2)
{
par1World.setBlockMetadataWithNotify(par2, par3, par4, 3, 2);
}
if (l == 3)
{
par1World.setBlockMetadataWithNotify(par2, par3, par4, 4, 2);
}
if (par6ItemStack.hasDisplayName())
{
((TileEntityBioFurnace)par1World.getBlockTileEntity(par2, par3, par4)).setCustomName(par6ItemStack.getDisplayName());
}
}
public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
{
if (!keepBioInventory)
{
TileEntityBioFurnace var7 = (TileEntityBioFurnace)par1World.getBlockTileEntity(par2, par3, par4);
if (var7 != null)
{
for (int var8 = 0; var8 < var7.getSizeInventory(); ++var8)
{
ItemStack itemstack = var7.getStackInSlot(var8);
if (itemstack != null)
{
float f = this.bioRand.nextFloat() * 0.8F + 0.1F;
float f1 = this.bioRand.nextFloat() * 0.8F + 0.1F;
float f2 = this.bioRand.nextFloat() * 0.8F + 0.1F;
while (itemstack.stackSize > 0)
{
int k1 = this.bioRand.nextInt(21) + 10;
if (k1 > itemstack.stackSize)
{
k1 = itemstack.stackSize;
}
itemstack.stackSize -= k1;
EntityItem entityitem = new EntityItem(par1World, (double)((float)par2 + f), (double)((float)par3 + f1), (double)((float)par4 + f2), new ItemStack(itemstack.itemID, k1, itemstack.getItemDamage()));
if (itemstack.hasTagCompound())
{
entityitem.getEntityItem().setTagCompound((NBTTagCompound)itemstack.getTagCompound().copy());
}
float f3 = 0.05F;
entityitem.motionX = (double)((float)this.bioRand.nextGaussian() * f3);
entityitem.motionY = (double)((float)this.bioRand.nextGaussian() * f3 + 0.2F);
entityitem.motionZ = (double)((float)this.bioRand.nextGaussian() * f3);
par1World.spawnEntityInWorld(entityitem);
}
}
}
par1World.func_96440_m(par2, par3, par4, par5);
}
}
super.breakBlock(par1World, par2, par3, par4, par5, par6);
}
public boolean hasComparatorInputOverride()
{
return true;
}
public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5)
{
return Container.calcRedstoneFromInventory((IInventory)par1World.getBlockTileEntity(par2, par3, par4));
}
}
and also I feel like I have to make a Render class but it doesn't anything on making one in the tutorial.
Base class...
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;
@Mod(modid = "BioFurnace", name = "BioFurnace", version = "1.0")
@NetworkMod(clientSideRequired = true, serverSideRequired = false)
public class BioFurnace
{
@Instance("BioFurnace")
public static BioFurnace instance;
private GuiHandlerBioFurnace guiHandlerBioFurnace = new GuiHandlerBioFurnace();
public static Block bioFurnaceOff;
public static Block bioFurnaceOn;
public static int bioFurnaceOffID;
public static int bioFurnaceOnID;
@SidedProxy(clientSide = "biocraft.ClientProxy", serverSide = "biocraft.ServerProxy")
public static ServerProxy proxy;
@EventHandler
public void PreInit(FMLPreInitializationEvent event)
{
}
@EventHandler
public void load(FMLInitializationEvent event)
{
bioFurnaceOff = new BlockBioFurnace(bioFurnaceOffID, false).setHardness(3.5F).setResistance(2000.0F).setStepSound(Block.soundStoneFootstep).setUnlocalizedName("bioFurnace");
bioFurnaceOn = new BlockBioFurnace(bioFurnaceOnID, true).setHardness(3.5F).setResistance(2000.0F).setStepSound(Block.soundStoneFootstep).setUnlocalizedName("bioFurnace");
//Game Reg.
GameRegistry.registerBlock(bioFurnaceOff, "highSpeedFurnace");
GameRegistry.registerBlock(bioFurnaceOn, "highSpeedFurnaceActive");
//Lang. Reg.
LanguageRegistry.addName(bioFurnaceOff, "HighSpeed Furnace");
//Tile Entity Reg.
GameRegistry.registerTileEntity(TileEntityBioFurnace.class,"tileEntitBioFurnace");
//Misc. Reg.
RenderingRegistry.registerBlockHandler(2105, RenderBio.INSTANCE);
NetworkRegistry.instance().registerGuiHandler(this, guiHandlerBioFurnace);
proxy.registerRenderThings();
}
@EventHandler
public void PostInit(FMLPostInitializationEvent event)
{
}
}
My previous/current work: Plantology
The easiest way involves a base edit; the hard way does involve creating a custom Render class that extends RenderBlocks.
Yeah, the way Shadow did it was just a copy of the render code in the render class (vanilla code) and tweaked it a bit. Some how he can see it in his head how some code works and getting him to explain well is not easy. He is kind of advanced in some ways, does great work with making custom mobs...check out the fossil mod revival he has done all the dino work there and made vast improvements over the original mod.
Find out how I generate....coolAlias...world structure generation and rotation tool...
I have tried multiple variations of my code and I can just not seem to get the results I am looking for. I am sure I probably have mistakes in both my TileEntity class and the FurnaceStack class. I think the combination of these two furnace types is confusing me and I am getting to the point where I just need some help. If you or even anyone else could take a look at my code if you get the time and help me out or at least tell me what I am doing wrong, that would be awesome! This is becoming a lot more complicated than I had thought it would be. Anyway, here are my classes.
TileEntity
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.ItemBlock;
import net.minecraft.item.ItemHoe;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemSword;
import net.minecraft.item.ItemTool;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import cpw.mods.fml.common.registry.GameRegistry;
public class TileEntityForgeGrayBrick extends TileEntity implements IInventory
{
private ItemStack blastItemStacks[];
public int dualBurnTime;
public int currentItemBurnTime;
public int dualCookTime1;
public int dualCookTime2;
public int ReduceAmount;
public ItemStack currentsmeltingitem;
public ItemStack currentItemBurnTime1;
private String customName;
public TileEntityForgeGrayBrick()
{
blastItemStacks = new ItemStack[8];
dualBurnTime = 0;
currentItemBurnTime = 0;
dualCookTime1 = 0;
dualCookTime2 = 0;
ReduceAmount = 1;
}
/**
* 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");
dualCookTime1 = nbttagcompound.getShort("CookTime1");
dualCookTime2 = nbttagcompound.getShort("CookTime2");
currentItemBurnTime = getItemBurnTime(blastItemStacks[1]);
currentsmeltingitem = blastItemStacks[3];
}
/**
* Writes a tile entity to NBT.
*/
public void writeToNBT(NBTTagCompound nbttagcompound)
{
super.writeToNBT(nbttagcompound);
nbttagcompound.setShort("BurnTime", (short)dualBurnTime);
nbttagcompound.setShort("CookTime1", (short)dualCookTime1);
nbttagcompound.setShort("CookTime2", (short)dualCookTime2);
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, int j)
{
if(j == 0)
{
return (dualCookTime1 * i) / 200;
} else
{
return (dualCookTime2 * 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(0, 1, 3) || canSmelt(4, 5, 6))
{
int i = getItemBurnTime(blastItemStacks[2]);
if(canSmelt(0, 1, 3) || canSmelt(4, 5, 6))
{
i = (int)((float)i * 0.79F);
}
currentItemBurnTime = dualBurnTime = i;
currentsmeltingitem = blastItemStacks[7] = blastItemStacks[2];
if(i > 0)
{
flag1 = true;
if(blastItemStacks[2] != null)
{
blastItemStacks[2].stackSize--;
if(blastItemStacks[2].stackSize == 0)
{
blastItemStacks[2] = null;
}
}
}
}
if (isBurning())
{
if(canSmelt(0, 1, 3))
{
dualCookTime1++;
if(dualCookTime1 == 200)
{
dualCookTime1 = 0;
smeltItem(0, 1, 3);
flag1 = true;
}
} else
{
dualCookTime1 = 0;
}
if(canSmelt(4, 5, 6))
{
dualCookTime2++;
if(dualCookTime2 == 200)
{
dualCookTime2 = 0;
smeltItem(4, 5, 6);
flag1 = true;
}
} else
{
dualCookTime2 = 0;
}
}
else
{
dualCookTime1 = 0;
dualCookTime2 = 0;
}
if (flag != (dualBurnTime > 0))
{
flag1 = true;
BlockForgeGrayBrick.updateFurnaceBlockState(this.dualBurnTime > 0, this.worldObj, this.xCoord, this.yCoord, this.zCoord);
}
}
if (flag1)
{
onInventoryChanged();
}
}
private boolean canSmelt(int i, int j, int k)
{
if (blastItemStacks[i] == null || blastItemStacks[1] == null)
{
return false;
}
ItemStack itemstack = FurnaceStackForgeGrayBrick.checkLargeFurnaceStack(blastItemStacks[i], blastItemStacks[2], this);
if (itemstack == null)
{
return false;
}
if (blastItemStacks[k] == null)
{
return true;
}
if (!blastItemStacks[k].isItemEqual(itemstack))
{
return false;
}
if (blastItemStacks[k].stackSize < getInventoryStackLimit() && blastItemStacks[k].stackSize < blastItemStacks[k].getMaxStackSize())
{
return true;
}
else
{
return blastItemStacks[k].stackSize < itemstack.getMaxStackSize();
}
}
public void smeltItem(int i, int j, int k)
{
if (!canSmelt(i, j, k))
{
return;
}
ItemStack itemstack = FurnaceStackForgeGrayBrick.checkLargeFurnaceStack(blastItemStacks[i], blastItemStacks[2], this);
if (blastItemStacks[k] == null)
{
blastItemStacks[k] = itemstack.copy();
}else
if (blastItemStacks[k].itemID == itemstack.itemID)
{
blastItemStacks[k].stackSize++;
}
if(blastItemStacks[i].stackSize - ReduceAmount <= 0)
{
blastItemStacks[i] = null;
} else
{
blastItemStacks[i].stackSize -= ReduceAmount;
}
}
public static int getItemBurnTime(ItemStack par0ItemStack)
{
if (par0ItemStack == null)
{
return 0;
}
else
{
int i = par0ItemStack.getItem().itemID;
Item item = par0ItemStack.getItem();
if (par0ItemStack.getItem() instanceof ItemBlock && Block.blocksList[i] != null)
{
Block block = Block.blocksList[i];
if (block == Block.woodSingleSlab)
{
return 150;
}
if (block.blockMaterial == Material.wood)
{
return 300;
}
}
//THis is where you would add any items you want to be used as fuel. The return value is the burn length.
if (item instanceof ItemTool && ((ItemTool) item).getToolMaterialName().equals("WOOD")) return 200;
if (item instanceof ItemSword && ((ItemSword) item).getToolMaterialName().equals("WOOD")) return 200;
if (item instanceof ItemHoe && ((ItemHoe) item).getMaterialName().equals("WOOD")) return 200;
if (i == Item.stick.itemID) return 100;
if (i == Item.coal.itemID) return 1600;
if (i == Item.bucketLava.itemID) return 20000;
if (i == Block.sapling.blockID) return 100;
if (i == Item.blazeRod.itemID) return 2400;
if (i == Item.rottenFlesh.itemID) return 400;
if (i == BigModMain.BucketOil.itemID) return 12000;
if (i == BigModMain.RawOil.itemID) return 2000;
if (i == BigModMain.CokeChunk.itemID) return 400;
return GameRegistry.getFuelValue(par0ItemStack);
}
}
/**
* 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 "Forge";
}
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 isStackValidForSlot(int i, ItemStack itemstack) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onInventoryChanged() {
// TODO Auto-generated method stub
}
}
FurnaceStack
import java.util.ArrayList;
import cpw.mods.fml.common.Mod.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.tileentity.TileEntityFurnace;
public class FurnaceStackForgeGrayBrick
{
public static int ReduceAmount;
private static int currentArray = 0;
private static ItemStack fuel[][] = new ItemStack[69][69];
private static ArrayList input = new ArrayList();
private static ArrayList output = new ArrayList();
private static ArrayList inputfuel = new ArrayList();
private static ArrayList outputfuel = new ArrayList();
public FurnaceStackForgeGrayBrick()
{
}
public static ItemStack checkStack(ItemStack aitemstack[], TileEntityForgeGrayBrick tileentity)
{
boolean flag = false;
if(aitemstack[0] != null)
{
for(int i = 0; i < input.size(); i++)
{
if(aitemstack[0].getItem() != ((ItemStack)input.get(i)).getItem() || aitemstack[0].getItemDamage() != ((ItemStack)input.get(i)).getItemDamage() || aitemstack[0].stackSize < ((ItemStack)input.get(i)).stackSize)
{
continue;
}
if(doesFuelMatch(tileentity.currentItemBurnTime1, i, aitemstack[2]))
{
tileentity.ReduceAmount = ((ItemStack)input.get(i)).stackSize;
return ((ItemStack)output.get(i)).copy();
}
flag = true;
}
}
if(flag)
{
return null;
} else
{
tileentity.ReduceAmount = 1;
return RecipesForge.getSmeltingResult(aitemstack[0].getItem().itemID, aitemstack[0].getItem().itemID);
}
}
public static void addSmeltingRecipe(ItemStack itemstack, ItemStack itemstack1)
{
if(itemstack == null || itemstack1 == null)
{
return;
} else
{
input.add(currentArray, itemstack);
output.add(currentArray, itemstack1);
fuel[currentArray][0] = null;
currentArray++;
return;
}
}
public static void addSmeltingRecipe(ItemStack itemstack, ItemStack itemstack1, ItemStack aitemstack[])
{
if(itemstack == null || itemstack1 == null || aitemstack == null)
{
return;
}
input.add(currentArray, itemstack);
output.add(currentArray, itemstack1);
int i = 0;
ItemStack aitemstack1[] = aitemstack;
int j = aitemstack1.length;
for(int k = 0; k < j; k++)
{
ItemStack itemstack2 = aitemstack1[k];
fuel[currentArray][i] = itemstack2;
i++;
}
currentArray++;
}
public static int checkFuel(ItemStack itemstack)
{
if(itemstack != null)
{
for(int i = 0; i < inputfuel.size(); i++)
{
if(itemstack.getItem() == ((ItemStack)inputfuel.get(i)).getItem() && itemstack.getItemDamage() == ((ItemStack)inputfuel.get(i)).getItemDamage())
{
return ((Integer)outputfuel.get(i)).intValue();
}
}
}
return -1;
}
public static void addSmeltingFuel(ItemStack itemstack, int i)
{
inputfuel.add(itemstack);
outputfuel.add(Integer.valueOf(i));
}
private static boolean doesFuelMatch(ItemStack itemstack, int i, ItemStack itemstack1)
{
if(fuel[i][0] == null)
{
return true;
}
if(itemstack1 != null)
{
for(int j = 0; i < fuel[i].length; j++)
{
if(fuel[i][j] == null)
{
return false;
}
if(fuel[i][j].getItem() == itemstack1.getItem() && fuel[i][j].getItemDamage() == itemstack1.getItemDamage())
{
return true;
}
}
} else
if(itemstack != null)
{
Item item = (Item) itemstack.getItem();
int k = itemstack.getItemDamage();
for(int l = 0; l < fuel[i].length; l++)
{
if(fuel[i][l] == null)
{
return false;
}
if(fuel[i][l].getItem() == item && fuel[i][l].getItemDamage() == k)
{
return true;
}
}
}
return false;
}
public static ItemStack checkLargeFurnaceStack(ItemStack itemstack, ItemStack itemstack1, TileEntityForgeGrayBrick tileentity)
{
ItemStack aitemstack[] = {
itemstack, itemstack1
};
boolean flag = false;
if(aitemstack[0] != null)
{
for(int i = 0; i < input.size(); i++)
{
if(aitemstack[0].getItem() != ((ItemStack)input.get(i)).getItem() || aitemstack[0].getItemDamage() != ((ItemStack)input.get(i)).getItemDamage() || aitemstack[0].stackSize < ((ItemStack)input.get(i)).stackSize)
{
continue;
}
if(doesFuelMatch(aitemstack[1], i, tileentity.currentsmeltingitem))
{
tileentity.ReduceAmount = ((ItemStack)input.get(i)).stackSize;
return ((ItemStack)output.get(i)).copy();
}
flag = true;
}
}
if(flag)
{
return null;
} else
{
tileentity.ReduceAmount = 1;
return RecipesForge.getSmeltingResult(aitemstack[0].getItem().itemID, aitemstack[0].getItem().itemID);
}
}
}
Container
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 ContainerForgeGrayBrick extends Container
{
private TileEntityForgeGrayBrick blast;
private int dualBurnTime;
private int dualCookTime1;
private int dualCookTime2;
private int lastItemBurnTime;
public ContainerForgeGrayBrick(InventoryPlayer inventoryplayer, TileEntityForgeGrayBrick tileEntity)
{
dualCookTime1 = 0;
dualCookTime2 = 0;
dualBurnTime = 0;
lastItemBurnTime = 0;
blast = tileEntity;
this.addSlotToContainer(new Slot(tileEntity, 0, 42, 17)); //First Input 1
this.addSlotToContainer(new Slot(tileEntity, 1, 70, 17)); //Second Input 1
this.addSlotToContainer(new Slot(tileEntity, 2, 17, 33)); //Fuel
this.addSlotToContainer(new SlotForge(inventoryplayer.player, tileEntity, 3, 116, 17)); //Output 1
this.addSlotToContainer(new Slot(tileEntity, 4, 42, 35)); //First Input 2
this.addSlotToContainer(new Slot(tileEntity, 5, 70, 35)); //Second Input 2
this.addSlotToContainer(new SlotForge(inventoryplayer.player, tileEntity, 6, 116, 35)); //Output 2
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.dualCookTime1);
par1ICrafting.sendProgressBarUpdate(this, 1, this.blast.dualBurnTime);
par1ICrafting.sendProgressBarUpdate(this, 2, this.blast.currentItemBurnTime);
par1ICrafting.sendProgressBarUpdate(this, 4, this.blast.dualCookTime2);
}
/**
* 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.dualCookTime1 != this.blast.dualCookTime1)
{
var2.sendProgressBarUpdate(this, 0, this.blast.dualCookTime1);
}
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);
}
if (this.dualCookTime2 != this.blast.dualCookTime2)
{
var2.sendProgressBarUpdate(this, 0, this.blast.dualCookTime2);
}
}
this.dualCookTime1 = this.blast.dualCookTime1;
this.dualCookTime2 = this.blast.dualCookTime2;
this.dualBurnTime = this.blast.dualBurnTime;
this.lastItemBurnTime = this.blast.currentItemBurnTime;
}
public void updateProgressBar(int i, int j)
{
if (i == 0)
{
blast.dualCookTime1 = j;
}
if (i == 1)
{
blast.dualBurnTime = j;
}
if (i == 2)
{
blast.currentItemBurnTime = j;
}
if (i == 4)
{
blast.dualCookTime2 = 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);
}
}
Okay....thanks for being efficient first of all....Take a look at my double furnace code. You will see that it has two inputs and two outputs. If you look into the tile entity there you will see that it is doubled up on everything but the fuel source. So taking that as an example, in your tile you will need to make the code reflect how that one works, having four inputs and two outputs using two fuel sources. So they only thing you really need to add is for the two more ins and one more out and one more fuel slot. If you read carefully through the code you can begin to see how these are implemented and should be able to add those in. You shouldn't need to change anything in the furnace stack code, however you will need to adjust the container in the crafters method and the detect and save method. I dont have the code in front of me right now, I was actually getting ready for bed (24 hours now and counting), but I will look at it tomorrow and see if I can mock something up to help.
Please forgive me I have been real busy lately recoding my structures in my mod for the use of a new tool for generation by coolAlias and is taking a considerable amount of time (78 structures).
Find out how I generate....coolAlias...world structure generation and rotation tool...
No worries man. I definitely understand being busy and if you do happen to get a chance to look at it, any help would be appreciated for sure, but for now I will take what you told me and keep working at it. I will post a reply if I happen to get it working so you know not to worry about it. Thanks micro!
Find out how I generate....coolAlias...world structure generation and rotation tool...
Thanks for the tutorial. I am looking at the very first tutorial. It looks like 3-4 classes are missing from the tutorial:
1) TileEntityFurnace
2) TileEntityHighSpeedFurnace
3) RenderHighSpeed
Also this line refers to two other classes, it seems:
@SidedProxy(clientSide = "bcblocks.highspeed.loco.ClientProxy", serverSide = "bcblocks.highspeed.loco.CommonProxy")
public static CommonProxy proxy;
Would it possible to have a look at those or can I just remove them? So far I have commented them out and moved on.
Thanks!