public virtual Result <BuyFromVendorResult <T> > BuyFromVendor(ICustomer <T> customer, T item, int amount = 1) { var canBuy = CanBuyFromVendor(customer, item, amount); if (canBuy.result == false) { return(new Result <BuyFromVendorResult <T> >(null, canBuy.error)); } // We make a clone of the item to make sure a new unique instance is returned. // In the scenario where the user sells part of a stack to the vendor and buys it back he/she would buy back the exact same item instance, causing an error. // NOTE: Try to find the specific item instance var index = vendorCollection.IndexOf(o => o?.item != null && ReferenceEquals(o.item, item)); if (index == -1) { // Couldn't find specific; Try to find an item that's equal to the one we want. index = vendorCollection.IndexOf(o => o?.item != null && o.item.Equals(item)); } // No item found; Abort! if (index == -1) { return(new Result <BuyFromVendorResult <T> >(null, Errors.VendorDoesNotContainItem)); } var buyProduct = vendorCollection[index]; if (amount < vendorCollection.GetAmount(index)) { // Not buying entire stack, so make a clone. buyProduct = (IVendorProduct <T>)buyProduct.Clone(); } if (config.removeBoughtProductFromVendor) { vendorCollection.Remove(buyProduct, amount); } foreach (var c in buyProduct.buyPrice) { vendorCurrencies.Add(c.currency, c.amount * amount * config.buyFromVendorPriceMultiplier); } customer.AddItem(buyProduct.item, amount); foreach (var c in buyProduct.buyPrice) { customer.RemoveCurrency(c.currency, c.amount * amount * config.buyFromVendorPriceMultiplier); } var buyResult = new BuyFromVendorResult <T>(customer, buyProduct, amount, buyProduct.buyPrice); OnBoughtFromVendor?.Invoke(this, buyResult); return(buyResult); }