Shyy Guy
Shyy Guy

Reputation: 242

Items in static List<Item>()

So I have a static item list which stores a few classes, and in those classes are variables such as "int ID", "string name", "string description", "int currentAmount", etc.

ItemDatabase.cs...

public static List<Item> Items

static void LoadItemData()
{
    Items.Add(new item);
    ...
}

I then have a separate item list which will have items added to it for use by the player.

Player.cs...

List<Item> playerItems;

Then in other classes, I have AddItem(int ID) methods:

void AddItem(int id)
{
    foreach (Item i in ItemDatabase.Items)
        if (i.ID == id)
            playerItems.Add(i);
}

I'm currently adding in entities that will make use of the same data. But when I modify the Item added to the playerItems, it modifies ItemDatabase.Items (Obviously, due to referencing).

I can't make the Item class into a struct, because I have other classes which derive from it. I need the "currentAmount" integer to be by value. Is there any way I can do this?

P.S., I've tried deep cloning, and that doesn't play nicely with my Item class.

Upvotes: 0

Views: 2607

Answers (4)

D Stanley
D Stanley

Reputation: 152511

Obviously you need to clone the objects if you want to change them without affecting the original. Serialization is one way to do a "deep clone" but as you have discovered not all types can be serialized.

If you are just modifying the first-level value type properties (not changing related item's values or references) you can use object.MemberwiseClone to create a shallow copy (copies of value types and references).

Upvotes: 1

celerno
celerno

Reputation: 1387

I'm still not sure where you are modifying ItemsDatabase.Items (currentAmount as property of the Entity doesn't makes much more sense), but for current amount in your Inventory, I guess this will help you:

Dictionary<Item, int> inventory = new Dictionary<Item, int>();

void AddItem(int id)
{
    foreach (Item i in ItemDatabase.Items)
        if (i.ID == id)
            {
              if(!inventory.Keys.Contains(i)){iventory.Add(i, 0);}
              inventory[i]+=1; //increment the amount of items in inventory.
            }
}

Important:

Dictionary uses Hash to get the object from dictionary, so, you probably want to override that method in your Item class:

class Item {
    public string Name;
    public string Description;
    public int currentAmount;

    public override int GetHashCode(){
       return Name.GetHashCode() + Description.GetHashCode();
    }
}

see more:

Upvotes: 0

aleha_84
aleha_84

Reputation: 8539

do this:

void AddItem(int id)
{
    var item = ItemDatabase.Items.FirstOrDefault(x=> x.ID == id);
    if(item!=null){
        playerItems.Add(new Item(){ ID = item.ID, Name = item.Name, etc... })
    }
}

Upvotes: 0

BradleyDotNET
BradleyDotNET

Reputation: 61339

You need to separate out currentAmount. Since that value only makes sense in the context of a Player anyways, I would take that out of the Item class, and use a Dictionary<Item,int> to keep track of the inventory:

Dictionary<Item, int> inventory = new Dictionary<Item, int>();

void AddItem(int id)
{
    foreach (Item i in ItemDatabase.Items)
        if (i.ID == id)
            playerItems.Add(i, 0); //Or whatever count
}

Upvotes: 1

Related Questions