Where is the documentation on transferStackInSlot(...) and mergeItemStack(...)? Looking through the code is too confusing without knowing what each parameter is. I can't figure out how to write shift-click code for my containers if I have no idea what each parameter does.
The functions in question are:
ItemStack transferStackInSlot(EntityPlayer player, int par2)
boolean mergeItemStack(ItemStack par1, int par2, int par3, boolean par4)
For the transferStackInSlot(…) function, par2 equals the slot id from where the player right clicked from. So if you have a custom slot, and it's id is 3, And there is coal in that slot. When the player right clicks on the coal, it will call this function with the parameters (player, 3). For more help, you could look in ContainerFurnace.class, it's very helpful because it's specific!
For the mergeItemStack(…) function, par1 is the ItemStack you want to merge, par2 is where the function will start trying to merge the ItemStack in the slots, par3 is where it will stop trying to merge the stack. par4 is if you want it to start from the bottom, other than the top. If you still don't understand, lets use an example below:
Let's take the Furnaces code:
public ItemStack transferStackInSlot(EntityPlayer player, int slotClicked)
{
ItemStack itemstack = null;
//This gets the slot that the player right clicked from.
Slot slot = (Slot)this.inventorySlots.get(slotClicked);
if (slot != null && slot.getHasStack())
{
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
//This is the cooked item slot, slot 0 is the raw item,
//slot 1 is the fuel and slot 2 is where to cooked item goes.
if (slotClicked == 2)
{
//This function is trying to send it to slots 3 all the way to 39 (Which is the players inventory)
//par4 is true, that means it will try to put it in the players hot-bar (All the ay at the bottom).
if (!this.mergeItemStack(itemstack1, 3, 39, true))
{
//If that doesn't work, return null...
return null;
}
//Declare the slot changed for the server and client...
slot.onSlotChange(itemstack1, itemstack);
}
//This means if the slot clicked isn't the raw slot, or not the fuel slot (meaning it's the inventory slot)
else if (slotClicked != 1 && slotClicked != 0)
{
//This means if it could be cooked in a furnace
if (FurnaceRecipes.smelting().getSmeltingResult(itemstack1) != null)
{
//This is trying to put it in the first (raw) slot.
if (!this.mergeItemStack(itemstack1, 0, 1, false))
{
//If that doesn't work, return null...
return null;
}
}
//This means if it is fuel for the furnace
else if (TileEntityFurnace.isItemFuel(itemstack1))
{
//This is trying to put it in the second (fuel) slot.
if (!this.mergeItemStack(itemstack1, 1, 2, false))
{
//If that doesn't work, return null...
return null;
}
}
//If it's not fuel, and can't be cooked, but it's in the inventory, not the hot-bar
else if (slotClicked >= 3 && slotClicked < 30)
{
//Just re place it in the inventory, not the hot-bar
if (!this.mergeItemStack(itemstack1, 30, 39, false))
{
//If that doesn't work, return null...
return null;
}
}
//If it's not fuel, and can't be cooked and it's in the hot-bar
else if (slotClicked >= 30 && slotClicked < 39)
{
//Try to place it in the inventory, not the hot-bar
if(!this.mergeItemStack(itemstack1, 3, 30, false))
{
//If that doesn't work, return null...
return null;
}
}
}
//If all else fails, try to put it somewhere in the inventory...
else if (!this.mergeItemStack(itemstack1, 3, 39, false))
{
//If that doesn't work, return null...
return null;
}
//If it's stack size is 0, set it to null...
if (itemstack1.stackSize == 0)
{
slot.putStack((ItemStack)null);
}
else
{
slot.onSlotChanged();
}
//If the stack sizes are equal, meaning the whole stack was transferred over, set it to null
if (itemstack1.stackSize == itemstack.stackSize)
{
return null;
}
slot.onPickupFromSlot(p_82846_1_, itemstack1);
}
//Return it when it's all done!
return itemstack;
}
Hope that helped, If you have any questions or problems let me know! Happy Modding!
I'm making a specialty furnace with two slots, one for ore and one for gravel (it works very similar to the TE Induction Smelter). I have constants for the slot id's as follows:
public static final int INPUT = 0;
public static final int FUEL = 1;
public static final int OUTPUT = 2;
public static final int GRAVEL = 3;
For some reason, I've gotten all of the shift-clicking to work as expected except the gravel (though through an odd way).
Here's my code for the slot setup (in the container constructor):
smelter = tileEntitySmelter;
addSlotToContainer(new Slot(tileEntitySmelter, TileEntitySmelter.INPUT, 46, 17));
addSlotToContainer(new Slot(tileEntitySmelter, TileEntitySmelter.GRAVEL, 66, 17));
addSlotToContainer(new Slot(tileEntitySmelter, TileEntitySmelter.FUEL, 56, 53));
addSlotToContainer(new SlotFurnace(playerInv.player, tileEntitySmelter, TileEntitySmelter.OUTPUT, 116, 35));
int i;
for (i = 0; i < 3; ++i)
{
for (int j = 0; j < 9; ++j)
{
addSlotToContainer(new Slot(playerInv, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
}
}
for (i = 0; i < 9; ++i)
{
addSlotToContainer(new Slot(playerInv, i, 8 + i * 18, 142));
}
and here's my code for transferStackInSlot(...), mostly copied from the furnace:
public ItemStack transferStackInSlot(EntityPlayer player, int clickedSlot)
{
ItemStack movedStackDupe = null;
Slot slot = (Slot)inventorySlots.get(clickedSlot);
The functions in question are:
Any idea which parameter means what?
For the mergeItemStack(…) function, par1 is the ItemStack you want to merge, par2 is where the function will start trying to merge the ItemStack in the slots, par3 is where it will stop trying to merge the stack. par4 is if you want it to start from the bottom, other than the top. If you still don't understand, lets use an example below:
Let's take the Furnaces code:
Hope that helped, If you have any questions or problems let me know! Happy Modding!
Hello!
For some reason, I've gotten all of the shift-clicking to work as expected except the gravel (though through an odd way).
Here's my code for the slot setup (in the container constructor):
and here's my code for transferStackInSlot(...), mostly copied from the furnace:
{
ItemStack movedStackDupe = null;
Slot slot = (Slot)inventorySlots.get(clickedSlot);
if (slot != null && slot.getHasStack())
{
ItemStack movedStack = slot.getStack();
movedStackDupe = movedStack.copy();
if (clickedSlot == TileEntitySmelter.OUTPUT)
{
if (!mergeItemStack(movedStack, 4, 40, true))
{
return null;
}
slot.onSlotChange(movedStack, movedStackDupe);
}
else if (clickedSlot != TileEntitySmelter.FUEL && clickedSlot != TileEntitySmelter.INPUT &&
clickedSlot != TileEntitySmelter.GRAVEL)
{
if (SmelterRecipeHandler.smelting().getSmeltingResult(movedStack) != null)
{
if (!mergeItemStack(movedStack, TileEntitySmelter.INPUT, TileEntitySmelter.INPUT + 1, false))
{
return null;
}
}
else if (movedStack.getItem() == Item.getItemFromBlock(Blocks.gravel))
{
if (!mergeItemStack(movedStack, TileEntitySmelter.GRAVEL, TileEntitySmelter.GRAVEL + 1, false))
{
return null;
}
}
else if (TileEntitySmelter.isItemFuel(movedStack))
{
if (!mergeItemStack(movedStack, TileEntitySmelter.FUEL + 1, TileEntitySmelter.FUEL + 2, false))
{
return null;
}
}
else if (clickedSlot >= 4 && clickedSlot < 31)
{
if (!mergeItemStack(movedStack, 31, 40, false))
{
return null;
}
}
else if (clickedSlot >= 31 && clickedSlot < 40 && !mergeItemStack(movedStack, 4, 31, false))
{
return null;
}
}
else if (!mergeItemStack(movedStack, 4, 40, false))
{
return null;
}
if (movedStack.stackSize == 0)
{
slot.putStack((ItemStack)null);
}
else
{
slot.onSlotChanged();
}
if (movedStack.stackSize == movedStackDupe.stackSize)
{
return null;
}
slot.onPickupFromSlot(player, movedStack);
}
return movedStackDupe;
}
What am I messing up?