So i find my self helping people out a lot in the forums so i thought it would be easier to put some of the more advanced topics i have covered in a tutorial post and then just link them as needed.
Storing Arbitrary Data in an item:
This will only working in 1.9 pre X or 1.0.0!
First i will show you an example and them explain what each part does.
In this example i will create a item that stores the cords of a block for no good reason.
public class ItemGPS extends Item{
public ItemGPS(int i) {
super(i);
}
@Override
public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) {
int x = loadX(itemstack);
saveCords(itemstack,i,j,k);
return true;
}
public void saveCords(ItemStack itemstack, int i,int j,int k) {
NBTTagCompound Tag = itemstack.getTagCompound();
if(Tag == null) {
Tag = new NBTTagCompound();
}
Tag.setInteger("x", i);
Tag.setInteger("y", j);
Tag.setInteger("z", k);
itemstack.setTagCompound(Tag);
}
public int loadX(ItemStack itemstack) {
NBTTagCompound Tag = itemstack.getTagCompound();
if(Tag == null || !Tag.hasKey("x")) {
return 0;
}
return Tag.getInteger("x");
}
}
Now first things first, items are always static! This means you cant store anything directly in them, ItemStacks act as the instances of an item.
The key to all of this is "itemstack.stackTagCompound", its a NBTTagCompound used to store enchantments (its get function is itemstack.getTagCompound() and its set function is itemstack.setTagCompound). In order to use this you have to find out what item stack your item is in this only happens when a onX method is called (in this case onItemUse).
In the example we use two functions i made: loadX and saveCords. loadX simply checks to see if x has been set then returns its value if it has, saveCords saves the 3 cords into x,y and z.
The ItemStack handles any of the loading and saving after that.
Good places to look for more info: ItemStack.getItemNameandInformation This returns a list of enchantments. ItemStack.addEnchantment itemstack.getTagCompound gets stackTagCompound (the NBTTagCompound) itemstack.setTagCompound sets stackTagCompound (the NBTTagCompound) itemstack.getEnchantmentTagList returns the enchantment NBTTagList
Removing Recipes:
Be careful when using this it may break other mods.
//Code by yope_fried inspired by pigalot
private static void RemoveRecipe(ItemStack resultItem) {
List<IRecipe> recipes = CraftingManager.getInstance().getRecipeList();
for (int i = 0; i < recipes.size(); i++)
{
IRecipe tmpRecipe = recipes.get(i);
if (tmpRecipe instanceof ShapedRecipes) {
ShapedRecipes recipe = (ShapedRecipes)tmpRecipe;
ItemStack recipeResult = recipe.getRecipeOutput();
if (ItemStack.areItemStacksEqual(resultItem, recipeResult)) {
recipes.remove(i--);
}
}
}
}
The first line of the function is the key here it pulls the list of recipes out of the CraftingManager, you just edit this list how ever you like.
Useing stackTagCompound to make a bag:
mod_BagMod:
package net.minecraft.src;
public class mod_BagMod extends BaseModMp{
public static final ItemBag itemBag = new ItemBag(2100);
@Override
public String getVersion() {
return "v0.2";
}
@Override
public void load() {
ModLoader.addName(itemBag, "Bag");
ModLoader.addRecipe(new ItemStack(itemBag), new Object[] {"# ", Character.valueOf('#'), Block.dirt});
}
}
ItemBag:
package net.minecraft.src;
public class ItemBag extends Item{
static int SIZE_OF_BAG = 36;
public ItemBag(int i) {
super(i);
setIconIndex(ModLoader.addOverride("/gui/items.png", "/bag.png"));
setItemName("Bag");
}
@Override
public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) {
openBagGUI(entityplayer,itemstack);
return itemstack;
}
public static void openBagGUI(EntityPlayer entityplayer, ItemStack itemStack) {
ModLoader.getMinecraftInstance().displayGuiScreen(
new GuiChest(entityplayer.inventory, new InventoryBag(itemStack))); //only works for SP
}
public static ItemStack[] loadBagContents(ItemStack itemStack) {
if(itemStack == null) return new ItemStack[SIZE_OF_BAG];
if(itemStack.stackTagCompound == null ) return new ItemStack[SIZE_OF_BAG];
NBTTagList nbttaglist = itemStack.stackTagCompound.getTagList("bagContents");
if(nbttaglist != null) {
ItemStack[] bagContents = new ItemStack[SIZE_OF_BAG];
for(int i = 0; i < nbttaglist.tagCount(); i++) {
NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i);
byte byte0 = nbttagcompound1.getByte("Slot");
if(byte0 >= 0 && byte0 < bagContents.length) {
bagContents[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
}
}
return bagContents;
}
return new ItemStack[SIZE_OF_BAG];
}
public static void saveBagContents(ItemStack itemStack, ItemStack[] bagContents) {
NBTTagList nbttaglist = new NBTTagList();
for(int i = 0; i < bagContents.length; i++) {
if(bagContents[i] != null) {
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
nbttagcompound1.setByte("Slot", (byte)i);
bagContents[i].writeToNBT(nbttagcompound1);
nbttaglist.appendTag(nbttagcompound1);
}
}
if(itemStack.stackTagCompound == null ) itemStack.stackTagCompound = new NBTTagCompound();
itemStack.stackTagCompound.setTag("bagContents", nbttaglist);
}
}
InventoryBag:
package net.minecraft.src;
public class InventoryBag implements IInventory{
ItemStack[] bagContents;
ItemStack bag;
public InventoryBag(ItemStack bag) {
this.bagContents = ItemBag.loadBagContents(bag);
this.bag = bag;
}
@Override
public int getSizeInventory() {
return ItemBag.SIZE_OF_BAG;
}
@Override
public ItemStack getStackInSlot(int i) {
return bagContents[i];
}
@Override
public ItemStack decrStackSize(int i, int j) {
if (bagContents[i] != null)
{
if (bagContents[i].stackSize <= j)
{
ItemStack itemstack = bagContents[i];
bagContents[i] = null;
onInventoryChanged();
return itemstack;
}
ItemStack itemstack1 = bagContents[i].splitStack(j);
if (bagContents[i].stackSize == 0)
{
bagContents[i] = null;
}
onInventoryChanged();
return itemstack1;
}
else
{
return null;
}
}
@Override
public void setInventorySlotContents(int i, ItemStack itemstack) {
bagContents[i] = itemstack;
if (itemstack != null && itemstack.stackSize > getInventoryStackLimit())
{
itemstack.stackSize = getInventoryStackLimit();
}
onInventoryChanged();
}
@Override
public String getInvName() {
return "Bag";
}
@Override
public int getInventoryStackLimit() {
return 64;
}
@Override
public void onInventoryChanged() {
ItemBag.saveBagContents(bag, bagContents);
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer) {
return true;
}
@Override
public void openChest() {
}
@Override
public void closeChest() {
onInventoryChanged();
}
@Override
public ItemStack func_48081_b(int i) {
return getStackInSlot(i);
}
}
Could you actually give us any sort of explanation as to how to remove a recipe? You just give us part of the code and tell us to edit it but don't say how it works!
Could you actually give us any sort of explanation as to how to remove a recipe? You just give us part of the code and tell us to edit it but don't say how it works!
The Meaning of Life, the Universe, and Everything.
Join Date:
10/19/2010
Posts:
245
Member Details
For anyone who is using the latest version of Forge (that is, the one for MC 1.4.7) there are a few modification to the Removing Recipes method. This method will work fine for most of the items, but in the end the you will not be able to remove 88 of the items. That is because Forge stores these items' recipes as "ShapedOreRecipe"s and "ShapelessOreRecipe"s.
I modified the code to work with all items. All we have to do is simply tell the method to reconize the ShapedOreRecipe and ShapelessOreRecipe items.
Storing Arbitrary Data in an item:
This will only working in 1.9 pre X or 1.0.0!
First i will show you an example and them explain what each part does.
In this example i will create a item that stores the cords of a block for no good reason.
Now first things first, items are always static! This means you cant store anything directly in them, ItemStacks act as the instances of an item.
The key to all of this is "itemstack.stackTagCompound", its a NBTTagCompound used to store enchantments (its get function is itemstack.getTagCompound() and its set function is itemstack.setTagCompound). In order to use this you have to find out what item stack your item is in this only happens when a onX method is called (in this case onItemUse).
In the example we use two functions i made: loadX and saveCords. loadX simply checks to see if x has been set then returns its value if it has, saveCords saves the 3 cords into x,y and z.
The ItemStack handles any of the loading and saving after that.
Good places to look for more info:
ItemStack.getItemNameandInformation This returns a list of enchantments.
ItemStack.addEnchantment
itemstack.getTagCompound gets stackTagCompound (the NBTTagCompound)
itemstack.setTagCompound sets stackTagCompound (the NBTTagCompound)
itemstack.getEnchantmentTagList returns the enchantment NBTTagList
Removing Recipes:
Be careful when using this it may break other mods.
The first line of the function is the key here it pulls the list of recipes out of the CraftingManager, you just edit this list how ever you like.
Useing stackTagCompound to make a bag:
mod_BagMod:
ItemBag:
InventoryBag:
An expansion on the first tutorial giving a useful example of how to create a portable chest.
Link to working mod(1.2.3) + src.
More to come please leave me any comments, or request on other things you would like explained.
Mmm these look to be really useful Wonder why its not getting much publicity :/
+1
Exactly my dilemma.
I modified the code to work with all items. All we have to do is simply tell the method to reconize the ShapedOreRecipe and ShapelessOreRecipe items.
Edit: This may not be necessary at all since I am apparently using an older version of the method....
Oh well