Jump to content

[new method] GameData should register an item with your own modcontainer?


AXELTOPOLINO
 Share

Recommended Posts

Hello everyone,

I'm working on a difficult mod and I'm adding some items in game during the game session.

I know this is highly discouraged, but there's an important reason if I'm doing it.

The problem is that when you register a new item during the game, GameData.newItemAdded() registers it with "Minecraft" as modContainer. Differently I'd like to use my mod's modContainer that I can get via "FMLCommonHandler.instance().findContainerFor(MyModCommon.instance)".

 

For this reason I need a change of the method GameData.newItemAdded(Item item) into GameData.newItemAdded(Item item, ModContainer container), so I can specify the ModContainer.

 

Could you add this feature please?

 

Thanks,

Axel

Link to comment
Share on other sites

  • 4 weeks later...

if you are already doing hacky stuff you might as well continue :D

Access Loader#modController to get the LoadController instance. Then access LoadController#activeModContainer and inject your modContainer. Then add the item. Then reset the activeModContainer again.

Of course you need reflection for this because the fields are private. And why the heck are you creating Items mid-game?!?

Link to comment
Share on other sites

First of all, thank you diesieben07 for your helpful reply (I have also clicked the "thanks" button :) ),

I have understood everything of your idea and it seems the very best solution, but even if I have coded many mods, I have never used reflection.

Could you link me some documentation about it? As you are right, I need to have access to the private fields.

 

Again thank you!

Axel

 

ps. creating Items mid-game? Look is 90% ready: http://www.minecraftforum.net/topic/1965419-wip162-axels-item-printer-create-your-custom-items-in-game/  ;D

Link to comment
Share on other sites

Could you link me some documentation about it? As you are right, I need to have access to the private fields.

Long answer: http://docs.oracle.com/javase/tutorial/reflect/

Short answer: http://stackoverflow.com/questions/1196192/how-do-i-read-a-private-field-in-java

You don't need to create a new Item instance for stuff like that. Make one Item which uses NBT to store the data.
Link to comment
Share on other sites

Could you link me some documentation about it? As you are right, I need to have access to the private fields.

Long answer: http://docs.oracle.com/javase/tutorial/reflect/

Short answer: http://stackoverflow.com/questions/1196192/how-do-i-read-a-private-field-in-java

You don't need to create a new Item instance for stuff like that. Make one Item which uses NBT to store the data.

 

I loved the long answer, I know how to use reflection now :)

 

Anyway you can't use an unique item instance for making more items with different stats. For example, even if there's only one class ItemSword.java, minecraft calls one instance of the wood sword, one for the iron sword, one for the diamond sword, etc. So I think we cannot use only one Item instance for all my custom items...or am I wrong (and I'd really like to be wrong)? :D

 

Thanks dude for your helpful support!

Axel

Link to comment
Share on other sites

Anyway you can't use an unique item instance for making more items with different stats. For example, even if there's only one class ItemSword.java, minecraft calls one instance of the wood sword, one for the iron sword, one for the diamond sword, etc. So I think we cannot use only one Item instance for all my custom items...or am I wrong (and I'd really like to be wrong)? :D

Yes, Mojang does that because vanilla has all the Item ids they want. They can create as many as they want because they don't have to worry about any restrictions. It's their game after all, they can change it if they need to. Modders can't.

Every ItemStack has an NBTTagCompound attached to it which allows you to store basically infinite amount of data into one ItemStack. Vanilla uses this feature for Enchantments, Written Books, etc.

Forge provides various hooks in the Item class to make the Item act dependent on the actual ItemStack being used. For example there is a new version of canHarvestBlock which gets the ItemStack being used as a parameter. Then this method can act differently depending on the Data on the NBTTagCompound of the ItemStack.

Link to comment
Share on other sites

Anyway you can't use an unique item instance for making more items with different stats. For example, even if there's only one class ItemSword.java, minecraft calls one instance of the wood sword, one for the iron sword, one for the diamond sword, etc. So I think we cannot use only one Item instance for all my custom items...or am I wrong (and I'd really like to be wrong)? :D

Yes, Mojang does that because vanilla has all the Item ids they want. They can create as many as they want because they don't have to worry about any restrictions. It's their game after all, they can change it if they need to. Modders can't.

Every ItemStack has an NBTTagCompound attached to it which allows you to store basically infinite amount of data into one ItemStack. Vanilla uses this feature for Enchantments, Written Books, etc.

Forge provides various hooks in the Item class to make the Item act dependent on the actual ItemStack being used. For example there is a new version of canHarvestBlock which gets the ItemStack being used as a parameter. Then this method can act differently depending on the Data on the NBTTagCompound of the ItemStack.

 

Anyway you can't use an unique item instance for making more items with different stats. For example, even if there's only one class ItemSword.java, minecraft calls one instance of the wood sword, one for the iron sword, one for the diamond sword, etc. So I think we cannot use only one Item instance for all my custom items...or am I wrong (and I'd really like to be wrong)? :D

Yes, Mojang does that because vanilla has all the Item ids they want. They can create as many as they want because they don't have to worry about any restrictions. It's their game after all, they can change it if they need to. Modders can't.

Every ItemStack has an NBTTagCompound attached to it which allows you to store basically infinite amount of data into one ItemStack. Vanilla uses this feature for Enchantments, Written Books, etc.

Forge provides various hooks in the Item class to make the Item act dependent on the actual ItemStack being used. For example there is a new version of canHarvestBlock which gets the ItemStack being used as a parameter. Then this method can act differently depending on the Data on the NBTTagCompound of the ItemStack.

That's quite interesting, but you cannot see in the creative menu the itemstacks, but only the items, then a new itemstack is created when you pick up an item. So your idea (which is a really smart one) can't be used for making completely different items in inventory. If I'm wrong, please tell me as it would be the final solution for the 32000 items limit :D
Link to comment
Share on other sites

That's quite interesting, but you cannot see in the creative menu the itemstacks, but only the items, then a new itemstack is created when you pick up an item. So your idea (which is a really smart one) can't be used for making completely different items in inventory. If I'm wrong, please tell me as it would be the final solution for the 32000 items limit :D

There are enchanted books in the creative inventory, right? And you can pick them up and they are still enchanted, right?

Now let me tell you that they all have the same ItemId and the same Damage value. The only difference between is their enchantments which are stored in the ItemStack's NBTTagCompound. When the ItemStack is cloned (on pickup from the creative inventory for example) the NBTTagCompound get's cloned, too.

Link to comment
Share on other sites

That's quite interesting, but you cannot see in the creative menu the itemstacks, but only the items, then a new itemstack is created when you pick up an item. So your idea (which is a really smart one) can't be used for making completely different items in inventory. If I'm wrong, please tell me as it would be the final solution for the 32000 items limit :D

There are enchanted books in the creative inventory, right? And you can pick them up and they are still enchanted, right?

Now let me tell you that they all have the same ItemId and the same Damage value. The only difference between is their enchantments which are stored in the ItemStack's NBTTagCompound. When the ItemStack is cloned (on pickup from the creative inventory for example) the NBTTagCompound get's cloned, too.

 

You are literally doing a revolution in my brain :D

So, how can I actually register different itemstacks when minecraft loads (I mean as Minecraft actually does), because I'd like to see them in the creative menu like the enchanted books.

 

Are there any troubles using Java reflection also after recompiling? I'm worried about fields name..

 

As always thanks for your time and patience!

Axel

Link to comment
Share on other sites

So, how can I actually register different itemstacks when minecraft loads (I mean as Minecraft actually does), because I'd like to see them in the creative menu like the enchanted books.

Override
getSubItems

in your Item class and add all the ItemStacks you want in the Creative menu to the list you get as the parameter.

Are there any troubles using Java reflection also after recompiling? I'm worried about fields name..

If you are accessing Minecraft fields/methods, yes there are issues because the fields and methods are obfuscated outside of MCP. But if you access FML or Forge stuff you'll be fine.
Link to comment
Share on other sites

So, how can I actually register different itemstacks when minecraft loads (I mean as Minecraft actually does), because I'd like to see them in the creative menu like the enchanted books.

Override
getSubItems

in your Item class and add all the ItemStacks you want in the Creative menu to the list you get as the parameter.

Are there any troubles using Java reflection also after recompiling? I'm worried about fields name..

If you are accessing Minecraft fields/methods, yes there are issues because the fields and methods are obfuscated outside of MCP. But if you access FML or Forge stuff you'll be fine.

 

For ItemStacks: wonderful, I'll let you know if it works (as I must have different itemstacks with 2 big arrays, some String values and some Int and Short values. This is why I thought itemStack weren't the right choice for doing something like this mod)

 

For reflection: I have reflected only FML fields now. But for curiosity: how can I know obfuscated names of fields and methods of MC? Should I check .class files and finding the right name or is there a public available list? Reflection would give us the possibility of avoiding base classes edits for modding :D

Link to comment
Share on other sites

For reflection: I have reflected only FML fields now. But for curiosity: how can I know obfuscated names of fields and methods of MC? Should I check .class files and finding the right name or is there a public available list? Reflection would give us the possibility of avoiding base classes edits for modding :D

In your forge source installation goto
forge/mcp/conf

. Open

methods.csv

with a text editor and find the unobfuscated name. It will give you a so called searge name for that function (

field_12345_xx

). Then open up

joined.srg

and search for that searge name, it will give you the final obfuscated name. Whenever you access a field via reflection you must search for all 3 names, you can use the Helper methods in FML's ReflectionHelper class for that.

Link to comment
Share on other sites

I know I'm a bit offtopic, but I'm trying to do what you suggested: using item subtypes instead of several different items.

I just have a question: I must create several types of swords, but if I use subtypes I cannot set different itemMaxDamage values.

 

Is there a way for doing it using subtypes?

 

Thanks in advance,

Axel

Link to comment
Share on other sites

All the weaponDamage does is create a new AttributeModifier on the Item. You can do that via NBT, too. Have a look at ItemStack#getAttributeModifiers where the per-item modifiers get computed. That should give you an idea of the NBT layout for AttributeModifiers.

 

Still working on it, trying to understand the idea correctly. First of all I haven't found the method ItemStack#getAttributeModifiers, is it probably func_111283_C()?

Anyway:

- I put N itemsubtypes using Item#getSubItems increasing the damage value for each subtype

- I can show subtypes in creative inventory thanks to Item#getCreativeTabs

 

But:

1) Which is the itemStack method that let me change the attribute modifiers of that itemstack only?

2) How can I damage an itemstack which uses an item subtype (for example it's a subtype of axe which should have a custom "MaxDamage", different from the other subtypes)

3) How can I add a new custom attribute modifier to the itemstack (like "acid-resistence")?

4) Can the nbtcompound be used for item subtypes that can be stackable?

 

I feel so newbie about this part of Minecraft code, but luckily you are helping us :)

Thank you,

Axel

Link to comment
Share on other sites

Still working on it, trying to understand the idea correctly. First of all I haven't found the method ItemStack#getAttributeModifiers, is it probably func_111283_C()?

Update forge, they updated the MCP mappings lately, it makes things a lot easier.

1) Which is the itemStack method that let me change the attribute modifiers of that itemstack only?

Use ItemStack.stackTagCompound to get the Stack NBT. Then look here: http://www.minecraftwiki.net/wiki/Player.dat_format#Attribute_Modifiers to find out about the format to use.

2) How can I damage an itemstack which uses an item subtype (for example it's a subtype of axe which should have a custom "MaxDamage", different from the other subtypes)

Override getMaxDamage(ItemStack), getDamage(ItemStack) and getDisplayDamage(ItemStack) and return the values you need depending on the NBT of the stack passed in.

3) How can I add a new custom attribute modifier to the itemstack (like "acid-resistence")?
Whenever you would apply acid damage to the player, check if he has your Item and if that item's NBT contains the "acid-resistant" flag.

4) Can the nbtcompound be used for item subtypes that can be stackable?

Items can be stacked if the NBT is equal.

 

Link to comment
Share on other sites

Still working on it, trying to understand the idea correctly. First of all I haven't found the method ItemStack#getAttributeModifiers, is it probably func_111283_C()?

Update forge, they updated the MCP mappings lately, it makes things a lot easier.

1) Which is the itemStack method that let me change the attribute modifiers of that itemstack only?

Use ItemStack.stackTagCompound to get the Stack NBT. Then look here: http://www.minecraftwiki.net/wiki/Player.dat_format#Attribute_Modifiers to find out about the format to use.

2) How can I damage an itemstack which uses an item subtype (for example it's a subtype of axe which should have a custom "MaxDamage", different from the other subtypes)

Override getMaxDamage(ItemStack), getDamage(ItemStack) and getDisplayDamage(ItemStack) and return the values you need depending on the NBT of the stack passed in.

3) How can I add a new custom attribute modifier to the itemstack (like "acid-resistence")?
Whenever you would apply acid damage to the player, check if he has your Item and if that item's NBT contains the "acid-resistant" flag.

4) Can the nbtcompound be used for item subtypes that can be stackable?

Items can be stacked if the NBT is equal.

 

Perfect, so I will just edit the Attribute modifier value for having a custom "damage" of the item (decreasing its value for consuming the itemstack), am I right?

 

The thing I wanted to ask in 4) is: Can the subtypes have different MaxStackSize? I really need this feature..

 

I hope my clicks on "thank you" button will be helpful for you, as you really deserve them :)

Axel

 

Edit: I'm stupid, I didn't see ItemStack#getMaxStackSize :D

 

Edit2: ItemStack#getMaxStackSize isn't subtype-sensitive as it calls ItemStack#getItem which is not subtype-sensitive. Is there any solution for that? Thanks :)

Link to comment
Share on other sites

Edit2: ItemStack#getMaxStackSize isn't subtype-sensitive as it calls ItemStack#getItem which is not subtype-sensitive. Is there any solution for that? Thanks :)

I don't think there is, at least not at the moment. Maybe make a PullRequest, as it's quite a simple change: add a new Method in Item
getMaxStackSize 

but which takes an Itemstack parameter and make the method in ItemStack call that one instead.

 

Link to comment
Share on other sites

I don't think there is, at least not at the moment. Maybe make a PullRequest, as it's quite a simple change: add a new Method in Item

getMaxStackSize 

but which takes an Itemstack parameter and make the method in ItemStack call that one instead.

 

Yes, I just hoped there was a forge edit already :)

Where should I pull the request? Here in this forge section or on github? Thanks

Link to comment
Share on other sites

Ok, not everything is NBT sensitive and the subitems are all loaded correctly.

 

I think this is almost obvious for you, but I still have one problem: how can I modify the ItemStack damage against EntityLivings if it is stored in the NBT of the itemstack (each subitem has got his own value for this field) ?

 

Thanks!

Axel

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.