private void Drop(InventoryItem item, int slot, ItemCollection collection)
        {
            if (!collection.Contains(item))
            {
                return;
            }

            if (collection[slot] != item)
            {
                return;
            }

            if (!collection.IsReferenceCollection)
            {
                NetworkController.Instance.Scene.UnregisterObjectAuthority(item.Identity);
            }

            Vector3    dropPos = transform.position + transform.forward + Vector3.up;
            Quaternion dropRot = transform.rotation;

            SharedRpcClientReleaseClaim(item.InstanceID, slot, GetCollectionIndex(collection), dropPos, dropRot);

            NetworkController.Instance.RemoteProcedures.Call(
                Identity,
                RPCType.All,
                nameof(SharedRpcClientReleaseClaim),
                item.InstanceID,
                slot,
                GetCollectionIndex(collection),
                dropPos,
                dropRot
                );
        }
        private void ClientRpcMoveItem(NetworkConnection conn, int instanceID, int fromCollectionIndex, int toCollectionIndex, int fromSlot, int toSlot)
        {
            NetworkIdentity identity       = NetworkIdentityManager.Instance.Get(instanceID);
            InventoryItem   item           = identity.GetComponent <InventoryItem>();
            ItemCollection  fromCollection = GetCollectionFromIndex(fromCollectionIndex);
            ItemCollection  toCollection   = GetCollectionFromIndex(toCollectionIndex);

            bool contains = toCollection.Contains(item);

            if (fromCollection == toCollection || !toCollection.IsReferenceCollection)
            {
                fromCollection[fromSlot] = null;
            }

            toCollection[toSlot] = item;

            if (!contains)
            {
                ItemAdded?.Invoke(toCollection, item, toSlot);
            }
            else
            {
                ItemMoved?.Invoke(fromCollection, toCollection, fromSlot, toSlot, item);
            }

            if (toCollection == fromCollection)
            {
                toCollection.RepaintUI();
                return;
            }

            if (fromCollection[fromSlot] == null)
            {
                ItemRemoved?.Invoke(fromCollection, item, fromSlot);
            }

            toCollection.RepaintUI();
            fromCollection.RepaintUI();
        }
        private void Move(InventoryItem fromItem, int fromSlot, ItemCollection fromCollection, int toSlot, ItemCollection toCollection)
        {
            if (!toCollection.IsAllowed(fromItem, toSlot))
            {
                return;
            }

            if (toCollection != fromCollection && toCollection.IsReferenceCollection && toCollection.Contains(fromItem))
            {
                return;
            }

            InventoryItem toItem = toCollection[toSlot];

            if (toItem != null)
            {
                // From and to reference collections cannot be combined or swapped only replaced and destroyed..
                if (!fromCollection.IsReferenceCollection && !toCollection.IsReferenceCollection)
                {
                    if (toCollection.CanStackInCollection && toItem.ItemID == fromItem.ItemID && toItem.Stack < toItem.MaxStack)
                    {
                        Combine(fromItem, toItem, fromCollection, toCollection);
                        return;
                    }

                    Swap(fromItem, fromCollection, fromSlot, toItem, toCollection, toSlot);
                    return;
                }
            }

            if (!toCollection.IsReferenceCollection && !toCollection.CanStackInCollection && fromItem.Stack > 1)
            {
                fromItem.Stack--;
                NotifyStackChanged(fromItem, fromCollection);

                GameObject inst = NetworkController.Instance.Scene.CreateForClient(
                    Identity.OwnerConnection,
                    m_ItemDatabase.GetItem(fromItem.ItemID).gameObject,
                    Vector3.zero, Quaternion.identity
                    );

                NetworkIdentity identity = inst.GetComponent <NetworkIdentity>();
                NetworkController.Instance.RemoteProcedures.Call(Identity, RPCType.All, nameof(SharedRpcClientClaim), identity.InstanceID);
                SharedRpcClientClaim(identity.InstanceID);
                toItem = identity.GetComponent <InventoryItem>();
                toCollection[toSlot] = toItem;

                ItemMoved?.Invoke(fromCollection, toCollection, fromSlot, toSlot, toItem);
                ItemAdded?.Invoke(toCollection, toItem, toSlot);

                NetworkController.Instance.RemoteProcedures.Call(
                    Identity,
                    RPCType.Target,
                    nameof(ClientRpcMoveItem),
                    Identity.OwnerConnection,
                    toItem.InstanceID,
                    GetCollectionIndex(toCollection), GetCollectionIndex(toCollection),
                    toSlot, toSlot);
                return;
            }

            // You can't move an item out of a reference collection...
            if (fromCollection.IsReferenceCollection && fromCollection != toCollection)
            {
                return;
            }

            bool contains = toCollection.Contains(fromItem);

            // Do not clear the item if it's a reference collection we're dragging to.
            if (fromCollection == toCollection || !toCollection.IsReferenceCollection)
            {
                fromCollection[fromSlot] = null;
            }

            toCollection[toSlot] = fromItem;
            if (!contains)
            {
                ItemAdded?.Invoke(toCollection, fromItem, toSlot);
            }
            else
            {
                ItemMoved?.Invoke(fromCollection, toCollection, fromSlot, toSlot, fromItem);
            }

            // Only need to invoke removal if the item becomes null.
            if (fromCollection[fromSlot] == null && fromCollection != toCollection)
            {
                ItemRemoved?.Invoke(fromCollection, fromItem, fromSlot);
            }

            NetworkController.Instance.RemoteProcedures.Call(
                Identity,
                RPCType.Target,
                nameof(ClientRpcMoveItem),
                Identity.OwnerConnection,
                fromItem.InstanceID,
                GetCollectionIndex(fromCollection),
                GetCollectionIndex(toCollection),
                fromSlot,
                toSlot);
        }