I have a block and an item, i want the item to be inserted into the block's inventory that is only 1 big. I want this to happen just by right click the item on the block.
I would also like the model of the block to change when an item is inserted, is it possible to do this without multiple TileEntities?
For changing the tile entity model, just do it in your tile entity logic the normal way. Or if you're using a custom block renderer, you can set metadata and check for it in it's renderer (setting metadata on a block will always cause a block render update).
With code. Just declare a field of ItemStack inventorySlot; in the class base, and pass the ItemStack from player (ensure it's not null first) from onBlockActivated as a parameter into your Tile Entity method, assign it to this tile entity field, then subtract one item from the players' hand stack. (with --player.getHeldItem().stacksize). You'll want your TileEntity method to return true or false and only remove item from players hand if it returns true though for example, the point being to make sure the tile entity can actually take this new item (i.e. it isn't already occupied), otherwise the item will disappear from the players hand and be lost in the void
Simple Java stuff, really. Make sure this field is also part of the save/load overrides for the Tile Entity, so the inventory content is saved with the world.
EDIT: An example can be seen in my CampfireLit block code. Note that my TileEntity does not do ANYTHING yet, I'm working on rendering for the moment.
EDIT2: Note that my "needUpdate" boolean stuff is missing too (it should be set to true once the itemstack is passed to tile entity), I think this is a good idea to do this but it may not be necessary.
Not sure the instanceof check is required, since it's our own block and we know what tile entity class it'll be. Unless it's possible for something else to add a second tile entity to the same block?
Anyway yeah that's the idea, see my code for taking an item away from the players' hand on right click.
public boolean onBlockActivated(World world, int varx, int vary, int varz, EntityPlayer entity, int p_149727_6_, float p_149727_7_, float p_149727_8_, float p_149727_9_) {
String altarType = altarName;
if (entity.inventory.getCurrentItem() != null) {
item = entity.inventory.getCurrentItem().getItem();
}
case "airrunealtar":
if (!world.isRemote) {
if (item == Items.airTalisman) {
int quantity;
world.setBlockToAir(varx, vary, varz);
world.setBlock(varx, vary, varz, Blocks.AirAltar);
world.spawnEntityInWorld(new EntityItem(world, varx, vary + 1, varz, new ItemStack(Items.airRune,numberOfRuneEssences)));
if (numberOfRuneEssences >= 5) {
int randomint = randInt(1, 5);
if (randomint == 1) {
int randomRune = randInt(0, 2);
switch (randomRune) {
case 0:
world.spawnEntityInWorld(new EntityItem(world, varx, vary + 1, varz, new ItemStack(Items.waterRune, 1)));
break;
case 1:
world.spawnEntityInWorld(new EntityItem(world, varx, vary + 1, varz, new ItemStack(Items.fireRune, 1)));
break;
case 2:
world.spawnEntityInWorld(new EntityItem(world, varx, vary + 1, varz, new ItemStack(Items.earthRune, 1)));
break;
}
}
randomint = 10;
item = null;
}
}
}
Ok so this turns the AirAltar into an AirAltar with a rune (AirRuneAltar), while also removing stack out of players hand. If then the rune altar is clicked with a talisman the new number of runes are output equal to the number taken away from the player. However what i have found is if i have two altars, and say i put 32 in one and 44 in another, if i go back to the 32 and use the talisman it gives me 44, because that was obviously the last value of rune essences used. I need to somehow save to each instance of altar how many essences i have used.
I would also like the model of the block to change when an item is inserted, is it possible to do this without multiple TileEntities?
For changing the tile entity model, just do it in your tile entity logic the normal way. Or if you're using a custom block renderer, you can set metadata and check for it in it's renderer (setting metadata on a block will always cause a block render update).
Simple Java stuff, really. Make sure this field is also part of the save/load overrides for the Tile Entity, so the inventory content is saved with the world.
EDIT: An example can be seen in my CampfireLit block code. Note that my TileEntity does not do ANYTHING yet, I'm working on rendering for the moment.
EDIT2: Note that my "needUpdate" boolean stuff is missing too (it should be set to true once the itemstack is passed to tile entity), I think this is a good idea to do this but it may not be necessary.
Anyway yeah that's the idea, see my code for taking an item away from the players' hand on right click.
public boolean onBlockActivated(World world, int varx, int vary, int varz, EntityPlayer entity, int p_149727_6_, float p_149727_7_, float p_149727_8_, float p_149727_9_) {
String altarType = altarName;
if (entity.inventory.getCurrentItem() != null) {
item = entity.inventory.getCurrentItem().getItem();
}
switch (tileEntityClass) {
case "airaltar":
if (item == Items.runeEssence) {
numberOfRuneEssences = entity.inventory.getCurrentItem().stackSize;
System.out.println(numberOfRuneEssences);
world.setBlockToAir(varx, vary, varz);
world.setBlock(varx, vary, varz, Blocks.AirRuneAltar);
entity.getHeldItem().stackSize = 0;
item = null;
}
case "airrunealtar":
if (!world.isRemote) {
if (item == Items.airTalisman) {
int quantity;
world.setBlockToAir(varx, vary, varz);
world.setBlock(varx, vary, varz, Blocks.AirAltar);
world.spawnEntityInWorld(new EntityItem(world, varx, vary + 1, varz, new ItemStack(Items.airRune,numberOfRuneEssences)));
if (numberOfRuneEssences >= 5) {
int randomint = randInt(1, 5);
if (randomint == 1) {
int randomRune = randInt(0, 2);
switch (randomRune) {
case 0:
world.spawnEntityInWorld(new EntityItem(world, varx, vary + 1, varz, new ItemStack(Items.waterRune, 1)));
break;
case 1:
world.spawnEntityInWorld(new EntityItem(world, varx, vary + 1, varz, new ItemStack(Items.fireRune, 1)));
break;
case 2:
world.spawnEntityInWorld(new EntityItem(world, varx, vary + 1, varz, new ItemStack(Items.earthRune, 1)));
break;
}
}
randomint = 10;
item = null;
}
}
}
Ok so this turns the AirAltar into an AirAltar with a rune (AirRuneAltar), while also removing stack out of players hand. If then the rune altar is clicked with a talisman the new number of runes are output equal to the number taken away from the player. However what i have found is if i have two altars, and say i put 32 in one and 44 in another, if i go back to the 32 and use the talisman it gives me 44, because that was obviously the last value of rune essences used. I need to somehow save to each instance of altar how many essences i have used.
I've not tested this on my end, I could have the same problem for all I know :\