I'm struggling with one piece of code and I was wondering if anyone could help me.
Here's my problem:
I'm working on a game and I created an inventory with a Dictionary. My Dictionary TKey is the item name and the TValue is a List. Each items has a boolean "isEquipped".
Dictionary<string, List<Item>> itemsInventory;
When equipping an item I want to check if the player has enough of this item and if this item can be equipped. I do that with this code:
public void EquipWeapon(bool tog, Item item)
{
if (tog == true)
{
if (player.weapon == false)
{
player.GetStatByName(item.StatAffectedName).AddModifier(item.StatAffectedValue, StatModifier.ModifierOrigins.Equipment, StatModifier.ModifierType.Flat, item.AssetName);
GameManagerSingleton.Instance.PlayerData.itemsInventory.FirstOrDefault(x => x.Key == item.AssetName && x.Value.Any(x => x.isEquiped == false)).Value.FirstOrDefault().isEquiped = true;
}
}
else
{
if (player.weapon == true)
{
player.GetStatByName(item.StatAffectedName).RemoveModifier(item.AssetName);
GameManagerSingleton.Instance.PlayerData.itemsInventory.FirstOrDefault(x => x.Key == item.AssetName && x.Value.Any(x => x.isEquiped == true)).Value.FirstOrDefault().isEquiped = false;
}
player.weapon = false;
}
player.GetStatByName(item.StatAffectedName).GetValue();
}
Problem with my code is that it changes all the items of the list and not just one. Anyone could help me please?
CodePudding user response:
From the comment you made "If I update in the debugger it change all items as well." it seems that the values in the list are the same object. This strongly suggests that Item
is a class
(not a struct
).
You need to clone the objects before adding them to the list if they represent different instances.
After I changed from false to true not only the item at index 0 but all objects changes.
CodePudding user response:
When I create the player, I create the Dictionary like this:
itemsInventory = new Dictionary<string, List<Item>>(),
And when I create the list it's like this:
Instance.PlayerData.itemsInventory.Add("weapon", new List<Item>());
Instance.PlayerData.itemsInventory.Add("armour", new List<Item>());
Instance.PlayerData.itemsInventory.Add("shield", new List<Item>());
CodePudding user response:
My code looked like this :
public void AddItemToInventory(Item? item, Ressource? ressource, int number = 1)
{
if (item != null)
{
int totalPrice = (item.Price * number);
ressources.First(x => x.currency == item.Currency).amount -= totalPrice;
DailyReportHandler.GetAndFillTodayReport().moneyForItems = totalPrice;
if (itemsInventory.ContainsKey(item.AssetName))
{
for (int i = 0; i < number; i )
{
itemsInventory.FirstOrDefault(x => x.Key == item.AssetName).Value.Add(item);
}
}
else
{
itemsInventory.Add(item.AssetName, new List<Item>());
for (int i = 0; i < number; i )
{
itemsInventory.FirstOrDefault(x => x.Key == item.AssetName).Value.Add(item);
}
}
}
if (ressource != null)
{
int totalPrice = (ressource.price * number);
ressources.First(x => x.currency == Currency.credit).amount -= totalPrice;
DailyReportHandler.GetAndFillTodayReport().moneyForItems = totalPrice;
GameManagerSingleton.Instance.PlayerData.AddResource(ressource.currency, number);
}
}
and I change it to this:
public void AddItemToInventory(Item? item, Ressource? ressource, int number = 1)
{
if (item != null)
{
int totalPrice = (item.Price * number);
ressources.First(x => x.currency == item.Currency).amount -= totalPrice;
DailyReportHandler.GetAndFillTodayReport().moneyForItems = totalPrice;
if (itemsInventory.ContainsKey(item.AssetName))
{
for (int i = 0; i < number; i )
{
itemsInventory.FirstOrDefault(x => x.Key == item.AssetName).Value.Add(GenerateNewItem(item));
}
}
else
{
itemsInventory.Add(item.AssetName, new List<Item>());
for (int i = 0; i < number; i )
{
itemsInventory.FirstOrDefault(x => x.Key == item.AssetName).Value.Add(GenerateNewItem(item));
}
}
}
if (ressource != null)
{
int totalPrice = (ressource.price * number);
ressources.First(x => x.currency == Currency.credit).amount -= totalPrice;
DailyReportHandler.GetAndFillTodayReport().moneyForItems = totalPrice;
GameManagerSingleton.Instance.PlayerData.AddResource(ressource.currency, number);
}
}
With GenerateNewItem(item)
like this:
public Item GenerateNewItem(Item item)
{
var newItem = new Item
{
AssetName = item.AssetName,
Currency = item.Currency,
DescriptionLocalizationKey = item.AssetName,
isEquiped = false,
itemType = item.itemType,
NameLocalizationKey = item.NameLocalizationKey,
Price = item.Price,
ShortDescriptionLocalizationKey = item.ShortDescriptionLocalizationKey,
StatAffectedName = item.StatAffectedName,
StatAffectedValue = item.StatAffectedValue
};
return newItem;
}