Is there something like Inventory.addItem(Items.ItemDefinition item, int amount)?

  • Hello,

    I'm trying to create a crafting wrapper which introduces some delay when crafting stuff.

    It's working quite fine by now yet I do have an issue.


    In order to add something to the inventory you need to know which function to call. There is:

    addClothingItem

    addConstructionItem

    addItem

    addObjectItem


    addItem for example works fine for lumber but it fails when trying to add a primitive workbench


    For now I didn't find a hint in the itemdefiniton which of the functions to use either ... not sure if i missed it.


    nevertheless. instead of having all those functions up there wouldn't it be way more easy to have a generic function which just takes the itemdef and an amount?

  • Basically it already works like that (more or less) ;) The game distinguishes between regular items (tools, weapons, food etc, basically everything that's solely used in inventory), objects (furniture, workbenches, doors, lamps), construction items (blocks) and clothing items.


    The addItem method is relevant for all regular items, i.e. all items which are represented by an ItemDefinition. In this case, the itemID is always the ID of the definition:

    Java
    Items.ItemDefinition itemDef = Definitions.getItemDefinition("pickaxe");
    inventory.addItem(itemDef.id, 0, 1);


    Objects (like the workbench) don't have an item definition (internally objects in inventory are almost always represented by a generic "objectkit" item which contains additional information to determine the actual object). If you write Definitions.getItemDefinition("workbench");, null is returned (because there is no item that is called "workbench", and the game does not have an ItemDefinition for this object).


    Objects are represented by ObjectDefinitions instead: to add an object (furniture, workbenches, doors, lamps etc) to the inventory, you have to use the addObjectItem method instead:

    Java
    Objects.ObjectDefinition objectDef = Definitions.getObjectDefinition("workbench");
    inventory.addObjectItem(objectDef.id, 0, 1);


    Clothes and construction items (blocks) use ClothingDefinitions and ConstructionDefinitions accordingly.


    To find out if you need to get an ObjectDefinition or ItemDefinition etc, you can use the description above as a rule of thumb (tools/weapons => item, furniture/workbenches => object etc). Alternatively you can take a look at the definitions.db file (in the game directory under Data/StreamingAssets/) , which contains all definitions. To open the file, you'll need an SQLite browser (like DB Browser or Navicat). Everything that's stored in the items table is represented by an ItemDefinition, everything that's stored in the objects table is represented by an ObjectDefinition, everything that's stored in the constructions table is represented by a ConstructionDefinition and everything in the clothes table is represented by a ClothingDefinition ;)

  • Hmmmm I had a feeling it was something like that. To be honest if it was just about a single item it would be fine to just look it up in the definitions db once.

    Yet that's not that much helpfull in my case as I want to create a generic wrapper which basicaly replaces the in game crafting. You might ask why I'd like to do that, to me the instantaneous crafting just doesn't feel right so I tried to create a short delay by aborting the original craft, start a timer, fill a progress bar and once a certain time has passed add the craft result to the player inventory ;-).

    Adding a custom list of crafts to the mod would work but is way to error prone to be a real solution so was hoping to get all information required to do so from the recipe.


    If I did understand upper text correct it might be possible to distinguish between items and object by using the getItemDefinition and getObjectInfoDefinition functions on the recipe output name ... I'm gonna give it a try.


    thanx for explaining :-)

  • try using the playercraftitemevent to get the item and use the example below.

  • To be honest I completely forgot about the item element in the event so I gave it a try. I gave my idea about the object and item definitions a try too.


    Sadly neither of them did work for common and different reasons


    first, there's no object definition for a primitive workbench but a item definition so using this as criteria to choose between addItem and addObjectItem doesn't work.

    That directly results in an issue with the solution james1bow suggested too because the item in the event is an ObjectItem in both cases too so there's no hint for what to use by using the item type either.


    on the way I discovered a further issue, how to add a blueprint item to the inventory? :-) ... well without the other issue solved that'd be just a question for curiosity :-)

  • i had to fight with it a bit as well. the fallowing code is the code i use for my auction house plugin.

  • Hello,


    thanks for your support I'm a little bit confused, the part wich is troubling me is not the side to find the item or recipe, my trouble is the other side. The place where the item goes to the players inventory.


    Code
    if (item instanceof Item.ObjectItem object)

    does tell true for both a workbench as well as for lumber.

    yet I can add lumber by calling


    Code
    player.getInventory().addItem(item.getTypeID(), item.getVariant(), 1);


    but this doesn't work for workbenches as red51 mentioned this just adds an objectkit.

    to be honest I could create my own lookuptable where I write the function to use to all the recipe/itemnames but that's something I'm really really reluctant to do ;-)


    I'm quite sure I'm missing something.

  • Yet that's not that much helpfull in my case as I want to create a generic wrapper which basicaly replaces the in game crafting. You might ask why I'd like to do that, to me the instantaneous crafting just doesn't feel right so I tried to create a short delay by aborting the original craft, start a timer, fill a progress bar and once a certain time has passed add the craft result to the player inventory ;-).

    You could grab the item from the PlayerCraftItemEvent and check what item it is, similar to how james1bow suggested above, e.g. like this:



    first, there's no object definition for a primitive workbench but a item definition so using this as criteria to choose between addItem and addObjectItem doesn't work.

    Primitive workbenches are objects, so they're represented by an ObjectDefinition. However, crafting recipes never store object definitions, they only store item definitions. In case of the workbench, the item definition references the generic "objectkit" item - this is how most objects are represented in inventory. Similar to the generic "constructionitem", which represents almost all construction elements, or the generic "clothingitem", which represented all types of clothes.


    But getting the correct item from a Recipe is indeed a bit tricky... internally the game stores some meta data (to determine the type of item) which is unfortunately not accessible by the API... what you could do is to check the RecipeType: If it's RecipeType.Object, you can use the recipe name to get an ObjectDefinition. If it's RecipeType.Clothing, use the recipe name to get a ClothingDefinition. If it's RecipeType.Block or RecipeType.Construction, you can get a ConstructionDefinition from the name. Else it's a regular item (where you can use the name to get an ItemDefinition).


    But if you're still inside the PlayerCraftItemEvent, it's still better to check the actual item instance (as mentioned above) ^^


    Having said that, I think it would be useful if we add a new addItem() method which just takes a String. There you could just provide the target item/object name and the game would automatically determine the type of item it has to add (this would work for items, but also for objects, clothes, construction elements etc) :)


    on the way I discovered a further issue, how to add a blueprint item to the inventory? :-) ... well without the other issue solved that'd be just a question for curiosity :-)

    Unfortunately there is no method to add a blueprint to the inventory yet (because there was little use for such a method yet, since a client could only use his local blueprints anyway). But I can put this on our to do list :)


    does tell true for both a workbench as well as for lumber.

    Hmm... that's not supposed to happen :wat: The condition if (item instanceof Item.ObjectItem object) should only be true for the workbench in this case, not for lumber. Are you sure it's true for lumber? Unfortunately I wasn't able to reproduce this on my end :thinking: If you use the code above for the PlayerCraftItemEvent, the output for lumber should be "Player crafted regular item: lumber"

  • first of all thanks for your patience :-)

    seems like my memory tricked me for the last point if (item instanceof Item.ObjectItem object) doesn't return true for lumber so you can ignore that point.


    I've found out a few things in between.

    1) you cant save the item provided in the event. start a timer and get the item back in the timer callback. While the object stored is still an item it seems to be empty at that point in time.

    I can only guess but I assume that I did my checks on that empty item last time what caused me think that lumber is an object item too.


    I guess I finaly found a solution, the last missing piece to the puzzle was not using the id from the item in the event but geting the ObjectDefiniton from the recipe name and use that one for addObject


    While I do understand that this is a result from how the data is structured in the game, IMHO for the api this is WAY to complicated ;-)

  • 1) you cant save the item provided in the event. start a timer and get the item back in the timer callback. While the object stored is still an item it seems to be empty at that point in time.

    Basically you can do that, but if you cache the item and use it at a later stage, make sure the item is still valid then (i.e. make sure the item hasn't been removed or disposed in the meantime). To do that, you can call item.isValid() ;)


    While I do understand that this is a result from how the data is structured in the game, IMHO for the api this is WAY to complicated ;-)

    As mentioned above, determining which item you have to add to the inventory based on a recipe is indeed a bit tricky, but a generic addItem() method which simply takes a String would definitely simplify this (you'll only need to pass recipe.name to the method then, without having to determine the recipe type) ^^

  • Basically you can do that, but if you cache the item and use it at a later stage, make sure the item is still valid then (i.e. make sure the item hasn't been removed or disposed in the meantime). To do that, you can call item.isValid() ;)

    hmmm I guess the "empty" item i had was invalid. what about rising an exception if someone calls a function if an invalid item? getTypeID()


    but a generic addItem() method which simply takes a String would definitely simplify this (you'll only need to pass recipe.name

    I guess that's a good idea but when trying to add clothing or construction i realized there's stuff like color or texture required too. I was to lazy to check but I have a feeling I would have to read that one from the item in the event and then use it later.


    Maybe instead of using the name, the onPlayerCraftItemEvent could get something like an extended recipe which contains not only the recipe definition but also all those additional parameters. If this full definition was a pure java object and could be arbitrarily stored it could be used at any time to create that object.

    Additionally the parameters could be modified too before really creating it.

  • hmmm I guess the "empty" item i had was invalid. what about rising an exception if someone calls a function if an invalid item? getTypeID()

    We could add that with the next update ;)


    I guess that's a good idea but when trying to add clothing or construction i realized there's stuff like color or texture required too. I was to lazy to check but I have a feeling I would have to read that one from the item in the event and then use it later.

    The addItem() method already has a "variant" parameter (which would also work for clothes or objects). In case of construction elements, the variant is just the texture - so this would also be covered by a generic addItem() method which takes a string.


    Setting colors, however, isn't possible that way. But we could "fix" that by adding a setColor() method to the according item instances, i.e Item.ConstructionItem etc ^^


    Maybe instead of using the name, the onPlayerCraftItemEvent could get something like an extended recipe which contains not only the recipe definition but also all those additional parameters. If this full definition was a pure java object and could be arbitrarily stored it could be used at any time to create that object.

    I'm not sure about that... it wouldn't be connected with the implementation on native side :thinking: Right now all definitions on Java side are generated automatically (based on the native definitions), because maintaining them manually would be a lot of work (and also quite error prone).


    Basically all definitions (including recipes) are intended to be generic and universally valid (i.e. not bound to a particular crafting action), so it never contains individual parameters (like the amount of items the player wants to craft or the optional color he defined)...

Participate now!

Don’t have an account yet? Create a new account now and be part of our community!