Use Properties Of An Item Without Actually Creating The Item?

Discuss modding questions and implementation details.
Post Reply
User avatar
Magicono43
Posts: 1141
Joined: Tue Nov 06, 2018 7:06 am

Use Properties Of An Item Without Actually Creating The Item?

Post by Magicono43 »

So i'm not really that familiar with the rules of Object Oriented Programming, so this question is probably going to sound really stupid. But anyway here it is, so the project i'm currently working on uses "DaggerfallUnityItem" objects and their properites A LOT, and the way I have currently been using has not seemed to cause any issues thus far, but I feel like i'm doing something wrong and would like to know if this is true or not.

With many numerous uses of this particular type of object, it also occurs often that I need to create these types of objects just as often as well to do the various logical checks and other things that I need to do. However, the problem that I see with this method of doing things, is that every time I create one of these objects, i'm also creating a new UID with that new item, and while this might not be a problem normally, if doing this potentially hundreds of times a second, I think this could eventually become a problem potentially.

So i'm wondering if there is some way that I can "create" an Item object for use of it's values attached to it alone, but not create it if you know what i'm trying to get at here? Like basically use it for it's data purposes, but not actually "create" a new instance of that object when doing my numerous logical operations and such using these created objects, it just does not seem right to me to do it like i'm doing in this regard, just leaving tens of thousands of objects with unique UIDs and hoping I won't hit some limit at some point for UIDs and then completely fuck a save or something.

The only thing I can think of is creating a new Constructor overload (if that's even possible) for this object and remove the assignment of a unique UID? But as I said, i'm not even sure if that is normally a thing you can do in OOP. Thanks.

Edit 1: Also to note, I have seem some code in the "ItemCollection" class mentioning in a comment something about using Item references to increase performance, but when I look at the code, it looks no different to me than what I have normally been seeing, so I don't really understand what a "reference" is compared to a full instance of an object in this regard, or how to use them.

l3lessed
Posts: 1409
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Re: Use Properties Of An Item Without Actually Creating The Item?

Post by l3lessed »

Yes, there is a better way of doing it.

You should create a empty daggerfallunityitem, call it something like "itemContainer'.

Then, anytime you need to load and use an item, instead of creating a whole new item and uid. dump it into the container and use the container object to reference.

This will insure every time you call a new item it overrides the old on in the container and doesn't leave bunch of uneeded/unused item objects.

You can also use a list object to load and override multiple items at once.

Here is single object example

Code: Select all

//setup the empty object to contain the item.	
    DaggerfallUnityItem containerItem;

//load first item into empty object to grab property without creating whole new object.
    containerItem = GameManager.Instance.PlayerEntity.Items.GetItem(UID#);
    int FirstItemPrice = containerItem.ItemTemplate.basePrice;
    
//load second item into object to grab property without creating whole new object. This will override the first one into the same object ensuring you don't leave a straggling object.
    containerItem = GameManager.Instance.PlayerEntity.Items.GetItem(UID#);
    int SecondItemPrice = containerItem.ItemTemplate.basePrice;
    
//and so on.    
Here is list example.

Code: Select all

   //create empty list to load multiple objects.
            List<DaggerfallUnityItem> ItemList;

//load all book items into empty list object.
            ItemList = GameManager.Instance.PlayerEntity.Items.SearchItems(ItemGroups.Books, (int)Books.Book0);
//grab properties from book1 and book2 item.
            int Book1ItemPrice = ItemList[0].ItemTemplate.basePrice;
            int Book2ItemPrice = ItemList[1].ItemTemplate.basePrice;

//clear out the list object by loading a blank new list into it.
            ItemList = new List<DaggerfallUnityItem>();
//load all armor items into empty list object.
            ItemList = GameManager.Instance.PlayerEntity.Items.SearchItems(ItemGroups.Armor, (int)Armor.Buckler);
//grab properties from armor1 and armor2 item.
            int Armor2ItemPrice = ItemList[0].ItemTemplate.basePrice;
            int Armor1ItemPrice = ItemList[1].ItemTemplate.basePrice;
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

User avatar
Magicono43
Posts: 1141
Joined: Tue Nov 06, 2018 7:06 am

Re: Use Properties Of An Item Without Actually Creating The Item?

Post by Magicono43 »

l3lessed wrote: Sat Jan 30, 2021 7:26 am Yes, there is a better way of doing it.

You should create a empty daggerfallunityitem, call it something like "itemContainer'.

Then, anytime you need to load and use an item, instead of creating a whole new item and uid. dump it into the container and use the container object to reference.

This will insure every time you call a new item it overrides the old on in the container and doesn't leave bunch of uneeded/unused item objects.

You can also use a list object to load and override multiple items at once.
Thanks a lot for the detailed reply, i'm going to try and use these methods you mentioned instead and see how it works out, (I don't think i'm going to actually notice any difference performance-wise in testing, but still at least there would be some peace of mind.)

Now an additional question is that, the objects I was creating in a wasteful way, without reusing UIDs and container objects and such, are they not volatile in some way as the program runs? Like when that method gets done running, would those objects not get deleted from memory or something, or would they only be saved if I placed them in currently running instances like the inventory of a loot-pile or something? I'm not really sure how this works in terms of internally as the program itself runs, like maybe my method of wastefully creating items and not expunging/overriding them is causing a sort of "memory leak" effect over time? Just something i'm curious about for optimization and understanding reasons, if you or anyone knows the answer, thanks.

Edit 1: Oh yeah, and in your examples you are populating the object container with objects that technically already exist, I.E those that are inside the item collection of the player. But can I do the same thing with items that I create exclusively through code that previously did not exist? Such as when I need to know all the items inside a specific Itemgroup and their properties. The only way I know how to use their properties and data is to actually create a new "DaggerfallUnityItem" object and act on that, if you know what I mean.

Edit 2: Like here is an example from part of my code for when generating potions based on some parameters.
Capture.JPG
Capture.JPG (51.44 KiB) Viewed 928 times
As you can see, with the "potChecked" object, i'm using the "CreatePotion" method to retrieve the object I want as to use it's specific parameters later in the loop. However, whenever this is ran it create a "new" instance of an item as far as I know, and i'm not sure if it's possible to get around that.

User avatar
Magicono43
Posts: 1141
Joined: Tue Nov 06, 2018 7:06 am

Re: Use Properties Of An Item Without Actually Creating The Item?

Post by Magicono43 »

Capture.JPG
Capture.JPG (23.7 KiB) Viewed 920 times
I'm going to experiment and add that constructor overload to see if it still works. If so than I won't have to really worry about the inefficient use of creating items like I have.

User avatar
Magicono43
Posts: 1141
Joined: Tue Nov 06, 2018 7:06 am

Re: Use Properties Of An Item Without Actually Creating The Item?

Post by Magicono43 »

Well, it seems to work for this purpose. The duplicate UIDs on the "reference" objects don't seem to cause any problems. I have to find where the game checks if UIDs of items are the same and throws and error, I know I have seen that somewhere in the code, but I forget where.

Maybe this will be my somewhat messy solution to my likely unfounded concern of UID overflow, lol.

User avatar
TheLacus
Posts: 1305
Joined: Wed Sep 14, 2016 6:22 pm

Re: Use Properties Of An Item Without Actually Creating The Item?

Post by TheLacus »

On a first look i don't believe is a good idea to alter id assignment in core. This could lead to a variety of unpredictable issues down the road and is probably not the best solution for your case.

Can you elaborate why you need to create these "dummy" items in the first place? If you need to check a value specific to all items of a kind, you should be able to access it directly from game data, there is no need to create fake items. Someone might be able to provide more help if you give an example of what you need.

User avatar
Magicono43
Posts: 1141
Joined: Tue Nov 06, 2018 7:06 am

Re: Use Properties Of An Item Without Actually Creating The Item?

Post by Magicono43 »

TheLacus wrote: Sat Jan 30, 2021 5:36 pm On a first look i don't believe is a good idea to alter id assignment in core. This could lead to a variety of unpredictable issues down the road and is probably not the best solution for your case.

Can you elaborate why you need to create these "dummy" items in the first place? If you need to check a value specific to all items of a kind, you should be able to access it directly from game data, there is no need to create fake items. Someone might be able to provide more help if you give an example of what you need.
Well it comes up often for me when working with my code, as I use the properties of specific items often to determine logical operations and other things and such, especially right now as I work on the loot system.
Capture.JPG
Capture.JPG (69.18 KiB) Viewed 914 times
Like say in that section of code. How could I determine potionEffect, without first determining potionRecipe, which requires a recipe Key, which can easily be retrieved by calling "PotionRecipeKey" on an already created potion item object.

I guess the "ItemsFile.cs" properties could be used for many of the general item properties of certain items, but what about ones like books that share the same base item file properties, but are changed after being created? Hopefully that made sense.

User avatar
TheLacus
Posts: 1305
Joined: Wed Sep 14, 2016 6:22 pm

Re: Use Properties Of An Item Without Actually Creating The Item?

Post by TheLacus »

You should be able to retrieve what you need directly from recipe key. There is no need to create a potion with that key, unless you actually want a real item to be added to the inventory.

Code: Select all

EntityEffectBroker entityEffectBroker = GameManager.Instance.EntityEffectBroker;

List<int> recipeKeys = entityEffectBroker.GetPotionRecipeKeys();

foreach (int key in recipeKeys)
{
    PotionRecipe potionRecipe = entityEffectBroker.GetPotionRecipe(key);
    IEntityEffect entityEffect = entityEffectBroker.GetPotionRecipeEffect(potionRecipe);
    // ...
}

User avatar
Magicono43
Posts: 1141
Joined: Tue Nov 06, 2018 7:06 am

Re: Use Properties Of An Item Without Actually Creating The Item?

Post by Magicono43 »

TheLacus wrote: Sat Jan 30, 2021 8:01 pm You should be able to retrieve what you need directly from recipe key. There is no need to create a potion with that key, unless you actually want a real item to be added to the inventory.

Code: Select all

EntityEffectBroker entityEffectBroker = GameManager.Instance.EntityEffectBroker;

List<int> recipeKeys = entityEffectBroker.GetPotionRecipeKeys();

foreach (int key in recipeKeys)
{
    PotionRecipe potionRecipe = entityEffectBroker.GetPotionRecipe(key);
    IEntityEffect entityEffect = entityEffectBroker.GetPotionRecipeEffect(potionRecipe);
    // ...
}
Alright, I'll give that a try, thanks.

Post Reply