예제 #1
0
        /**
         * <summary>Inserts an inventory item instance into a specific index in the collection.  If the item exists in another collection, it will be removed from there automatically.</summary>
         * <param name="addInstance">The inventory item instance to add</param>
         * <param name="index">The index to insert the item at</param>
         * <param name="occupiedSlotBehaviour">How to react if the intended index is already occupied by another item instance.</param>
         * <returns>The new instance of the added item</returns>
         */
        public InvInstance Insert(InvInstance addInstance, int index, OccupiedSlotBehaviour occupiedSlotBehaviour = OccupiedSlotBehaviour.ShiftItems)
        {
            // Adds to a specific index, or the end/first empty slot if -1
            if (!CanAccept(addInstance, index, occupiedSlotBehaviour))
            {
                if (InvInstance.IsValid(addInstance))
                {
                    if (KickStarter.eventManager)
                    {
                        KickStarter.eventManager.Call_OnUseContainerFail(addInstance.GetSourceContainer(), addInstance);
                    }
                }
                return(null);
            }

            InvInstance addedInstance = null;

            if (Contains(addInstance))
            {
                if (!CanReorder())
                {
                    return(addInstance);
                }

                if (MaxSlots > 0 && index >= MaxSlots)
                {
                    return(addInstance);
                }

                occupiedSlotBehaviour = OccupiedSlotBehaviour.SwapItems;
            }

            int numAdded = -1;

            InvCollection fromCollection = (Contains(addInstance)) ? this : addInstance.GetSource();

            if (index >= 0 && index < invInstances.Count)
            {
                // Inside
                InvInstance existingInstance = invInstances[index];

                if (!InvInstance.IsValid(existingInstance))
                {
                    // Empty slot
                    addedInstance = addInstance.CreateTransferInstance();

                    if (InvInstance.IsValid(addedInstance))
                    {
                        numAdded            = addedInstance.Count;
                        invInstances[index] = addedInstance;
                    }
                }
                else
                {
                    if (existingInstance == addInstance)
                    {
                        // Same
                        return(existingInstance);
                    }
                    else if (existingInstance.InvItem == addInstance.InvItem && addInstance.InvItem.canCarryMultiple && existingInstance.Capacity > 0)
                    {
                        // Merge
                        if (addInstance.TransferCount > existingInstance.Capacity)
                        {
                            addInstance.TransferCount = existingInstance.Capacity;
                        }
                        numAdded = Mathf.Min(addInstance.CreateTransferInstance().Count, existingInstance.Capacity);
                        existingInstance.Count += numAdded;
                        addedInstance           = existingInstance;
                    }
                    else
                    {
                        switch (occupiedSlotBehaviour)
                        {
                        case OccupiedSlotBehaviour.ShiftItems:
                            invInstances.Insert(index, addInstance.CreateTransferInstance());
                            addedInstance = invInstances[index];
                            break;

                        case OccupiedSlotBehaviour.FailTransfer:
                            if (InvInstance.IsValid(addInstance))
                            {
                                if (KickStarter.eventManager)
                                {
                                    KickStarter.eventManager.Call_OnUseContainerFail(addInstance.GetSourceContainer(), addInstance);
                                }
                                return(null);
                            }
                            break;

                        case OccupiedSlotBehaviour.SwapItems:
                            if (fromCollection != null)
                            {
                                if (addInstance.IsPartialTransform())
                                {
                                    if (KickStarter.eventManager)
                                    {
                                        KickStarter.eventManager.Call_OnUseContainerFail(addInstance.GetSourceContainer(), addInstance);
                                    }
                                    return(null);
                                }

                                fromCollection.invInstances[fromCollection.IndexOf(addInstance)] = existingInstance;
                                invInstances[index] = addInstance;
                                addedInstance       = invInstances[index];

                                if (KickStarter.runtimeInventory.SelectedInstance == addInstance)
                                {
                                    KickStarter.runtimeInventory.SelectItem(existingInstance);
                                }
                            }
                            break;

                        case OccupiedSlotBehaviour.Overwrite:
                            if (KickStarter.eventManager)
                            {
                                KickStarter.eventManager.Call_OnChangeInventory(this, existingInstance, InventoryEventType.Remove);
                            }
                            invInstances[index] = addInstance.CreateTransferInstance();
                            addedInstance       = invInstances[index];
                            break;

                        default:
                            break;
                        }
                    }
                }
            }
            else
            {
                // Add to first empty slot, or end
                bool addedInside = false;

                if (index < 0)
                {
                    // Find first empty slot
                    for (int i = 0; i < invInstances.Count; i++)
                    {
                        if (!InvInstance.IsValid(invInstances[i]))
                        {
                            invInstances[i] = addInstance.CreateTransferInstance();
                            addedInstance   = invInstances[i];
                            index           = i;
                            addedInside     = true;
                            break;
                        }
                        else if (invInstances[i] == addInstance)
                        {
                            return(addInstance);
                        }
                    }
                }

                if (!addedInside)
                {
                    if (maxSlots > 0 && invInstances.Count >= maxSlots)
                    {
                        return(null);
                    }

                    if (index > 0 && CanReorder())
                    {
                        while (invInstances.Count < index)
                        {
                            invInstances.Add(null);
                        }
                    }

                    invInstances.Add(addInstance.CreateTransferInstance());
                    addedInstance = invInstances[invInstances.Count - 1];
                }
            }

            if (fromCollection != null && fromCollection != this)
            {
                fromCollection.Clean();
            }

            Clean();
            PlayerMenus.ResetInventoryBoxes();

            if (KickStarter.eventManager)
            {
                if (numAdded >= 0)
                {
                    KickStarter.eventManager.Call_OnChangeInventory(this, addedInstance, InventoryEventType.Add, numAdded);
                }
                else
                {
                    KickStarter.eventManager.Call_OnChangeInventory(this, addedInstance, InventoryEventType.Add);
                }
            }
            return(addedInstance);
        }
예제 #2
0
        private bool CanAccept(InvInstance invInstance, int slot = -1, OccupiedSlotBehaviour occupiedSlotBehaviour = OccupiedSlotBehaviour.ShiftItems)
        {
            if (!InvInstance.IsValid(invInstance))
            {
                return(false);
            }

            if (invInstances.Contains(invInstance))
            {
                return(true);
            }

            if (!invInstance.InvItem.canCarryMultiple && Contains(invInstance.InvItem.id))
            {
                return(false);
            }

            if (ItemBlockedByCategory(invInstance.InvItem))
            {
                return(false);
            }

            if (KickStarter.runtimeInventory != null && KickStarter.runtimeInventory.PlayerInvCollection == this)
            {
                Container sourceContainer = GetSourceContainer(invInstance);
                if (sourceContainer && !KickStarter.runtimeInventory.CanTransferContainerItemsToInventory(sourceContainer, invInstance))
                {
                    return(false);
                }
            }

            if (slot >= 0 && slot < invInstances.Count)
            {
                InvInstance existingInstance = invInstances[slot];

                if (!InvInstance.IsValid(existingInstance))
                {
                    return(true);
                }

                if (InvInstance.IsValid(existingInstance) && existingInstance.InvItem == invInstance.InvItem && invInstance.InvItem.canCarryMultiple && existingInstance.Capacity >= invInstance.TransferCount)
                {
                    return(true);
                }
            }

            if (maxSlots > 0 && invInstances.Count >= maxSlots)
            {
                // Full
                switch (occupiedSlotBehaviour)
                {
                case OccupiedSlotBehaviour.FailTransfer:
                case OccupiedSlotBehaviour.ShiftItems:
                    return(false);

                default:
                    break;
                }
            }

            return(true);
        }