Zero quantity item problem
The documentation says that in order to transfer an item from one inventory to another, you need to remove an entry and add this entry like this:
public void TransferItem (IItemEntryReadOnly item, int quantity, IInventoryInstance from, IInventoryInstance to) {
from.RemoveEntry(item.Id, quantity);
to.AddEntry(item);
}
inventory.TransferItem(entry, 1, playerInventory, chestInventory);
However, this doesn't work when you try to transfer an item that is not unique, and you transfer the whole quantity of the item. The quantity is set to 0 in the new inventory. This happens because RemoveEntry function sets the quantity of the entry to 0 and the same item later being added to the new inventory by reference.
It could worth to update the documentation explaining that in such cases one must set the quality by hand or perhaps adding item by definition instead. Additionally, to that, perhaps inventory should print a warning that an item added has 0 quantity.
So this scenario should work. I'll have to make sure there are tests with RemoveEntry and AddEntry for unique and non-unique. Are you sure this is happening with non-unique items? I'm wondering if this bug only happens with unique items. Regardless I'll check the test suite on my next pass.
Yes I am sure. Look (code from InventoryInstance):
public void RemoveEntry (string entryId, int quantity = 1) {
var entry = _idToEntry[entryId];
// Leave the implementation up to the remove method
if (!entry.Definition.Unique) {
Remove(entry.Definition, quantity);
return;
}
_uniqueEntries.Remove(entry);
_idToEntry.Remove(entry.Id);
Events.ItemRemoved.Invoke(entry);
Events.ItemChanged.Invoke(entry);
}
If not unique then you remove by definition
Then you subtract quantity and then remove if it's 0
public void Remove (IItemDefinition item, int quantity = 1) {
if (item.Unique) throw new System.ArgumentException("Unique items cannot be removed by definition. Use an ID instead");
var entry = _entries[item];
entry.SetQuantity(entry.Quantity - quantity);
if (entry.Quantity <= 0) {
_entries.Remove(item);
_idToEntry.Remove(entry.Id);
}
Events.ItemRemoved.Invoke(entry);
Events.ItemChanged.Invoke(entry);
}
The problem is that the same entry that just was set quantity to 0 get's transferred to another inventory
Imagine
Inventory A has 3 sticks, none unique, it's just one entry
We get this entry and call RemoveEntry with quantity 3.
Now we have entry of sticks with quantity 0 (it's out of Inventory A)
and we transfer it to Inventory B by calling AddEntry
Now we have Inventory B with 0 sticks
Ah it's that chunk of code >_>. Yeah that was causing some issues I previously patched. This is all clicking. The unique entry support is powerful but created a few edge cases for sure.