Hello everybody
i'm looking for a way to remove an item from a player inventory.
here is my code but it doesnt work with this exception:
Code:
And this is the exception:Code:if (iitem.info.shortname == item_name && iitem.amount == item_count) { player.inventory.containerMain.itemList.Remove(iitem); }
[Oxide] 22:34 [Error] Web request callback raised an exception (InvalidOperationException: Collection was modified; enumeration operation may not execute.)
[Oxide] 22:34 [Debug] at System.Collections.Generic.List`1+Enumerator[Item].VerifyState () [0x00000] in <filename unknown>:0
at System.Collections.Generic.List`1+Enumerator[Item].MoveNext () [0x00000] in <filename unknown>:0
at Oxide.Plugins.InventoryInfo.PostCallbackval (Int32 code, System.String response, .BasePlayer player, System.String[] arr, System.String transaktion) [0x00000] in <filename unknown>:0
at Oxide.Plugins.InventoryInfo+<PostRequestfin>c__AnonStorey0.<>m__0 (Int32 code, System.String response) [0x00000] in <filename unknown>:0
at Oxide.Core.Libraries.WebRequests+WebRequest.<OnComplete>m__1 () [0x00000] in <filename unknown>:0
Is there a better way to remove an item by name from inventory?
Solved Removing an item from player inventory? (C#)
Discussion in 'Rust Development' started by Sir BenSon, Aug 15, 2016.
-
Looks like you are you trying to remove it in a foreach loop? If so use a for loop
The proper way to take a item is using the take method which requires a item ID.
Off the top of my head phone edit:
Code:var itemDef = ItemManager.FindItemDefinition(shortname); if (itemDef != null) player.inventory.Take(itemDef.info.itemID, amount);
Last edited by a moderator: Aug 15, 2016 -
Code:
private void TakeResources(BasePlayer player, int itemid, int amount) => player.inventory.Take(null, itemid, amount);
-
Mhh now it works with the first Item but than it crashed in an exception
i get via webrequest the items and the itemamount. I split the string in an array. I take the player main inventory in a list of items and with foreach i check my webrequest with the items in the list. if this correkt i will remove this. but it works only with the first item.
The itemarray looks like this and its split in an array with ";"
item=amount;item=amount;item=amount;
Code:List<Item> items = player.inventory.containerMain.itemList; foreach (string itemstring in arr) { string[] itemval = itemstring.Split("=".ToCharArray()); string item_name = itemval[0]; int item_count = int.Parse(itemval[1]); foreach (Item iitem in items) { if (iitem.info.shortname == item_name && iitem.amount == item_count) { var itemDef = ItemManager.FindItemDefinition(item_name); player.inventory.Take(null, itemDef.itemid, item_count); } } }
Code:[Error] Web request callback raised an exception (InvalidOperationException: Collection was modified; enumeration operation may not execute.) [Oxide] 23:26 [Debug] at System.Collections.Generic.List`1+Enumerator[Item].VerifyState () [0x00000] in <filename unknown>:0 at System.Collections.Generic.List`1+Enumerator[Item].MoveNext () [0x00000] in <filename unknown>:0 at Oxide.Plugins.InventoryInfo.PostCallbackval (Int32 code, System.String response, .BasePlayer player, System.String[] arr, System.String transaktion) [0x00000] in <filename unknown>:0 at Oxide.Plugins.InventoryInfo+<PostRequestfin>c__AnonStorey0.<>m__0 (Int32 code, System.String response) [0x00000] in <filename unknown>:0 at Oxide.Core.Libraries.WebRequests+WebRequest.<OnComplete>m__1 () [0x00000] in <filename unknown>:0
-
That's fine, switch the foreach loop to a for loop.
[DOUBLEPOST=1471298758][/DOUBLEPOST]The other thing you should do is check the inventory for the item and amount. Problem being they may have enough of the item, but spread over a few stacks, and the way you are doing it won't detect that. Maybe @DylanSMR can post that snippet aswell, there's a example in the same plugin he got the above one from -
Switching the first / second or both loops?
-
The one that loops through the inventory. You cant remove entries from a list or dictionary in a foreach loop. If I was driving a truck in peek hour traffic right now id give you a better explanation
-
Mh ok
but i store the items in a new list of items. so if i remove an item from the collection, the itemlist is the same or?
-
Ok now it works
Thanks a lot
[Finished] -
Code:
private bool HasEnoughRes(BasePlayer player, int itemid, int amount) => player.inventory.GetAmount(itemid) >= amount;