Reputation: 242
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
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
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
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
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