Forum rules - please read before posting.

Possible container bug

I have a heavily edited "inventory box type" custom script for inventories and containers, but I believe this is an AC bug:

  • If you have a container limited by category, and you select an item from a disallowed category in your inventory and click on one of the container slots, AC correctly denies the transfer. It also denies it if you click on an occupied container slot for an item swap. However, if you select an item from inside the container, and click on a disallowed item in your inventory, AC will do the swap and the disallowed item will end up in the container.

I believe this is similar to a bug I reported last year (which has been fixed):

Suppose ItemA has "can carry multiple?" unchecked. There is one copy of ItemA in your inventory, and another copy in the container. If you click on the container copy and take it to the inventory, the inventory (correctly) won't take it. But if you take a different item (ItemD) from the inventory and click on the container copy of ItemA, they will swap places and you will have two copies of ItemA even though you aren't supposed to!

Comments

  • Thanks for the details, I'll attempt a recreation.

  • edited September 2022

    Can you share details/screenshots of the InventoryBox element that causes the issue? If you're using a custom script to handle it's behaviour, please share it as well.

  • Here it is there whole thing:

    using AC;
    using UnityEngine;
    
    public class CustomInventories : MonoBehaviour
    {
    
        private void OnEnable() { EventManager.OnMenuElementClick += OnMenuElementClick; }
        private void OnDisable() { EventManager.OnMenuElementClick -= OnMenuElementClick; }
    
        private void OnMenuElementClick(Menu menu, MenuElement element, int slot, int buttonPressed)
        {
    
    
            MenuInventoryBox inventoryBox = element as MenuInventoryBox;
            InvInstance clickedInstance = inventoryBox.GetInstance(slot);
            InvInstance selectedInstance = KickStarter.runtimeInventory.SelectedInstance;
            InvCollection collectionClicked;
            InvCollection collectionSelected;        
    
            if (inventoryBox != null && inventoryBox.inventoryBoxType == AC_InventoryBoxType.CustomScript && menu.title != "Container Drawer (No Interaction)")
            {
    
    
                // Click on an occupied slot while holding another item
                if (InvInstance.IsValid(clickedInstance) && InvInstance.IsValid(selectedInstance))
                {
                    collectionClicked = clickedInstance.GetSource();
                    collectionSelected = selectedInstance.GetSource();
    
                    // Swap items if the selected item came from a different collection (if multiple can be carried, add to stack)
                    if (collectionClicked != collectionSelected)
                    {
    
                        // Do nothing when items are the same and multiples are not allowed
                        if (!clickedInstance.InvItem.canCarryMultiple && clickedInstance.InvItem.maxCount < 2 && selectedInstance.ItemID == clickedInstance.ItemID)
                        {
                            KickStarter.runtimeInventory.SetNull();
                            return;
                        }
    
                        collectionClicked.Insert(selectedInstance, slot, OccupiedSlotBehaviour.SwapItems);
                        KickStarter.runtimeInventory.SetNull();
                        return;
                    }
                    // Combine items if they both come from the same collection
                    else
                    {
                        // Dealing with stackable items
                        if (clickedInstance.InvItem.canCarryMultiple && clickedInstance.InvItem.maxCount > 1 && selectedInstance.ItemID == clickedInstance.ItemID)
                        {
                            // Merge stacks
                            if (buttonPressed == 1)
                            {
                               collectionClicked.Insert(selectedInstance, slot, OccupiedSlotBehaviour.SwapItems);
                               KickStarter.runtimeInventory.SetNull();
                                return;
                            }
                            // Take one from stack
                            if (buttonPressed == 2)
                            {
                                KickStarter.runtimeInventory.SelectItem(clickedInstance);
                                return;
                            }
                        }
                        selectedInstance.Combine(clickedInstance, false);                    
                        return;
                    }
                }
    
                // Place item in free slot
                if (!InvInstance.IsValid(clickedInstance) && InvInstance.IsValid(selectedInstance))
                {
    
                    InvCollection collection = (inventoryBox.title == "Container") ? inventoryBox.OverrideContainer.InvCollection : KickStarter.runtimeInventory.PlayerInvCollection;
    
                    collection.Insert(KickStarter.runtimeInventory.SelectedInstance, slot, OccupiedSlotBehaviour.SwapItems);
                    KickStarter.runtimeInventory.SetNull();
                    return;
                }
    
                // Click on an item without holding anything
                if (InvInstance.IsValid(clickedInstance) && !InvInstance.IsValid(selectedInstance))
                {
    
                    // Dealing with stackable items
                    if (clickedInstance.InvItem.canCarryMultiple && clickedInstance.InvItem.maxCount > 1)
                    {
                        // Take all by left clicking
                        if (buttonPressed == 1)
                        {
                            int count = clickedInstance.Count;
                            while (count > 0)
                            {
                                KickStarter.runtimeInventory.SelectItem(clickedInstance);
                                count--;
                            }                        
                        }
                        // Take one from stack by right clicking
                        if (buttonPressed == 2)
                        {
                            KickStarter.runtimeInventory.SelectItem(clickedInstance);
    
                            // Just a test, used to delete one item from the stack if you want consumable items
                            // collectionClicked = clickedInstance.GetSource();
                            // collectionClicked.Delete(clickedInstance, 1);
    
                        }
                        return;
                    }
    
                    // Take item by left clicking
                    if (buttonPressed == 1)
                    {
                        KickStarter.runtimeInventory.SelectItem(clickedInstance);
                        return;
                    }
                    // Use action by right clicking
                    if (buttonPressed == 2)
                    {
                        clickedInstance.Use();
                        return;
                    }
    
    
    
                }
    
    
    
            }
    
    
    
        }
    }
    

    This is the offending bit:

    collectionClicked.Insert(selectedInstance, slot, OccupiedSlotBehaviour.SwapItems);

  • Copy/paste this above it:

    Container sourceContainer = collectionSelected.GetSourceContainer ();
    if (sourceContainer && sourceContainer.limitToCategory && sourceContainer.categoryIDs.Contains (clickedInstance.InvItem.id)) return;
    
  • edited September 2022

    sourceContainer.categoryIDs.Contains (clickedInstance.InvItem.id)

    It doesn't work because this is returning false, but it definitely should be returning true because the item is not in a category that is allowed (and AC automatically recognises this when you try to swap it the other way around, selecting the disallowed item in the inventory and clicking on an item in the container).

  • edited September 2022

    Just done some testing: the issue here is that sourceContainer.categoryIDs is a list of categoryIDs, not of item IDs within each categoryID.

  • My mistake.

    Container sourceContainer = collectionSelected.GetSourceContainer ();
    if (sourceContainer && sourceContainer.limitToCategory && sourceContainer.categoryIDs.Contains (clickedInstance.InvItem.binID)) return;
    
  • edited September 2022

    Ah thanks! Minor adjustment:

    Container sourceContainer = collectionSelected.GetSourceContainer();
    if (sourceContainer && sourceContainer.limitToCategory && (sourceContainer.categoryIDs.Contains(clickedInstance.InvItem.binID) == false)) return;
    

    Since we want to prevent the interaction if the item's category isn't checked as allowed (categoryIDs is a whitelist, not a blacklist).

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.