Bug? When item is removed in shop menu then Null warning appears

Hi,

I am not quite sure if it is a bug or using remove item over expected "boundaries" :)

I added an item remove operation with confirmation pop box in shop menu. When player click right mouse button on item in shop menu I show a confirmation pop window. When player confirmed the operation the item is remove. However, If I remove this item and mouse is over an empty item view slot then I get the following warning: "Cannot get the price of a NULL item" from method
C#:
protected CurrencyCollection GetPrice(ItemInfo itemInfo)
        {
            if (itemInfo.Item == null) {
                Debug.LogWarning("Cannot get the price of a NULL item");
                return null;
            }
            var shop = (Shop)m_Shop;

            if (m_IsBuying) {
                if (shop.TryGetBuyValueForBuyer(m_Inventory, itemInfo, ref m_TempCurrencyCollection)) {
                    return m_TempCurrencyCollection;
                }
            } else {
                if (shop.TryGetSellValueForSeller(m_Inventory, itemInfo, ref m_TempCurrencyCollection)) {
                    return m_TempCurrencyCollection;
                }
            }

            var buySell = m_IsBuying ? "Buy" : "Sell";
            Debug.LogWarning($"Was unable to find the {buySell} price for item: " + itemInfo);

            return null;
        }

The source of the problem is in method:
C#:
protected virtual void OnItemSelected(ItemViewSlotEventData slotEventData)
        {
            if (m_ShopperClientCurrencyOwner == null || m_Inventory == null) {
                Debug.LogError("The client inventory is either null or it does not have a currencyOwner.", gameObject);
                return;
            }
            var itemInfo = slotEventData.ItemViewSlot.ItemInfo;

            if (m_QuantityPickerPanel.IsOpen == false) { return; }
            if (m_SelectedItemInfo.Item == itemInfo.Item) { return; }

            m_SelectedItemInfo = itemInfo;
            m_QuantityPickerPanel.SetPreviousSelectable(slotEventData.ItemViewSlot);

            m_QuantityPickerPanel.QuantityPicker.MinQuantity = 1;
            if (m_IsBuying) {
                var price = GetPrice((1, itemInfo));
                var quotient = m_ShopperClientCurrencyOwner.PotentialQuotientFor(price);

                var max = Mathf.Max(quotient, 1);
                if (m_LimitBuyQuantityToAvailableItemAmount) {
                    max = Mathf.Min(max, itemInfo.Amount);
                }
                m_QuantityPickerPanel.QuantityPicker.MaxQuantity = max;

                m_QuantityPickerPanel.ConfirmCancelPanel.EnableConfirm(quotient > 0);
            } else {
                m_QuantityPickerPanel.QuantityPicker.MaxQuantity = itemInfo.Amount;
            }

            m_QuantityPickerPanel.QuantityPicker.SetQuantity(1);

            var quantity = m_QuantityPickerPanel.QuantityPicker.Quantity;

            DrawPriceTo((quantity, m_SelectedItemInfo), m_TotalPrice);
        }

in line
C#:
var itemInfo = slotEventData.ItemViewSlot.ItemInfo;
ItemInfo is set to None.
ItemInfoNone.jpg

What should I do to not destroy the flow of the code? :p
Regards
 
I temporary fix (?) this by add checking itemInfo:

C#:
protected virtual void OnItemSelected(ItemViewSlotEventData slotEventData)
        {
            if (m_ShopperClientCurrencyOwner == null || m_Inventory == null) {
                Debug.LogError("The client inventory is either null or it does not have a currencyOwner.", gameObject);
                return;
            }
            var itemInfo = slotEventData.ItemViewSlot.ItemInfo;

            if (m_QuantityPickerPanel.IsOpen == false) { return; }
            if (m_SelectedItemInfo.Item == itemInfo.Item) { return; }

            if(itemInfo == ItemInfo.None)
                return;
            
            m_SelectedItemInfo = itemInfo;
            m_QuantityPickerPanel.SetPreviousSelectable(slotEventData.ItemViewSlot);

            m_QuantityPickerPanel.QuantityPicker.MinQuantity = 1;
            if (m_IsBuying) {
                var price = GetPrice((1, itemInfo));
                var quotient = m_ShopperClientCurrencyOwner.PotentialQuotientFor(price);

                var max = Mathf.Max(quotient, 1);
                if (m_LimitBuyQuantityToAvailableItemAmount) {
                    max = Mathf.Min(max, itemInfo.Amount);
                }
                m_QuantityPickerPanel.QuantityPicker.MaxQuantity = max;

                m_QuantityPickerPanel.ConfirmCancelPanel.EnableConfirm(quotient > 0);
            } else {
                m_QuantityPickerPanel.QuantityPicker.MaxQuantity = itemInfo.Amount;
            }

            m_QuantityPickerPanel.QuantityPicker.SetQuantity(1);

            var quantity = m_QuantityPickerPanel.QuantityPicker.Quantity;

            DrawPriceTo((quantity, m_SelectedItemInfo), m_TotalPrice);
        }
 
Thanks for letting me know, I removed the warning, it shouldn't have been there from the beginning.

Code:
/// <summary>
/// Get the price of an item amount.
/// </summary>
/// <param name="itemInfo">The item.</param>
/// <returns>The currency collection.</returns>
protected CurrencyCollection GetPrice(ItemInfo itemInfo)
{
    if (itemInfo.Item == null) {
        return null;
    }
    var shop = (Shop)m_Shop;
    if (m_IsBuying) {
        if (shop.TryGetBuyValueForBuyer(m_Inventory, itemInfo, ref m_TempCurrencyCollection)) {
            return m_TempCurrencyCollection;
        }
    } else {
        if (shop.TryGetSellValueForSeller(m_Inventory, itemInfo, ref m_TempCurrencyCollection)) {
            return m_TempCurrencyCollection;
        }
    }
    var buySell = m_IsBuying ? "Buy" : "Sell";
    Debug.LogWarning($"Was unable to find the {buySell} price for item: " + itemInfo);
    return null;
}

I also made some changes when the selected item info is none
Code:
/// <summary>
/// The event when selecting an item.
/// </summary>
/// <param name="slotEventData">The slot event data.</param>
protected virtual void OnItemSelected(ItemViewSlotEventData slotEventData)
{
    if (m_ShopperClientCurrencyOwner == null || m_Inventory == null) {
        Debug.LogError("The client inventory is either null or it does not have a currencyOwner.", gameObject);
        return;
    }
    var itemInfo = slotEventData.ItemViewSlot.ItemInfo;
    if (m_QuantityPickerPanel.IsOpen == false) { return; }
    if (m_SelectedItemInfo.Item == itemInfo.Item) { return; }
    m_SelectedItemInfo = itemInfo;
    m_QuantityPickerPanel.SetPreviousSelectable(slotEventData.ItemViewSlot);
    if (m_SelectedItemInfo == ItemInfo.None) {
        m_QuantityPickerPanel.QuantityPicker.MinQuantity = 0;
        m_QuantityPickerPanel.QuantityPicker.MaxQuantity = 0;
        m_QuantityPickerPanel.QuantityPicker.SetQuantity(0);
        DrawPriceTo((0, m_SelectedItemInfo), m_TotalPrice);
        return;
    }
    m_QuantityPickerPanel.QuantityPicker.MinQuantity = 1;
    if (m_IsBuying) {
        var price = GetPrice((1, itemInfo));
        var quotient = m_ShopperClientCurrencyOwner.PotentialQuotientFor(price);
        var max = Mathf.Max(quotient, 1);
        if (m_LimitBuyQuantityToAvailableItemAmount) {
            max = Mathf.Min(max, itemInfo.Amount);
        }
        m_QuantityPickerPanel.QuantityPicker.MaxQuantity = max;
        m_QuantityPickerPanel.ConfirmCancelPanel.EnableConfirm(quotient > 0);
    } else {
        m_QuantityPickerPanel.QuantityPicker.MaxQuantity = itemInfo.Amount;
    }
    m_QuantityPickerPanel.QuantityPicker.SetQuantity(1);
    var quantity = m_QuantityPickerPanel.QuantityPicker.Quantity;
    DrawPriceTo((quantity, m_SelectedItemInfo), m_TotalPrice);
}

I also added the same change to on item clicked
Code:
/// <summary>
/// The event when clicking an item.
/// </summary>
/// <param name="slotEventData">The inventory grid UI.</param>
protected virtual void OnItemClicked(ItemViewSlotEventData slotEventData)
{
    if (m_OpenQuantityPickerOnItemClick == false) { return; }
    var itemInfo = slotEventData.ItemViewSlot.ItemInfo;
    if (itemInfo.Item == null) { return; }
    m_SelectedItemInfo = itemInfo;
    m_QuantityPickerPanel.Open(m_InventoryGrid.Panel, slotEventData.ItemViewSlot);
    
    if (m_SelectedItemInfo == ItemInfo.None) {
        m_QuantityPickerPanel.QuantityPicker.MinQuantity = 0;
        m_QuantityPickerPanel.QuantityPicker.MaxQuantity = 0;
        m_QuantityPickerPanel.QuantityPicker.SetQuantity(0);
        DrawPriceTo((0, m_SelectedItemInfo), m_TotalPrice);
        return;
    }
    m_QuantityPickerPanel.QuantityPicker.MinQuantity = 1;
    if (m_IsBuying) {
        var price = GetPrice((1, itemInfo));
        var quotient = m_ShopperClientCurrencyOwner.PotentialQuotientFor(price);
        var max = Mathf.Max(quotient, 1);
        if (m_LimitBuyQuantityToAvailableItemAmount) {
            max = Mathf.Min(max, itemInfo.Amount);
        }
        m_QuantityPickerPanel.QuantityPicker.MaxQuantity = max;
        m_QuantityPickerPanel.ConfirmCancelPanel.EnableConfirm(quotient > 0);
        m_QuantityPickerPanel.ConfirmCancelPanel.SetConfirmText("Buy");
    } else {
        m_QuantityPickerPanel.QuantityPicker.MaxQuantity = itemInfo.Amount;
        m_QuantityPickerPanel.ConfirmCancelPanel.EnableConfirm(true);
        m_QuantityPickerPanel.ConfirmCancelPanel.SetConfirmText("Sell");
    }
    m_QuantityPickerPanel.QuantityPicker.SetQuantity(1);
    var quantity = m_QuantityPickerPanel.QuantityPicker.Quantity;
    DrawPriceTo((quantity, m_SelectedItemInfo), m_TotalPrice);
}

Let me know if that works better for you. I'll add those changes to the next update
 
Top