void TransferItem(DaggerfallUnityItem item, ItemCollection from, ItemCollection to)
        {
            // Block transfer of horse or cart
            if (item.IsOfTemplate(ItemGroups.Transportation, (int)Transportation.Horse) ||
                item.IsOfTemplate(ItemGroups.Transportation, (int)Transportation.Small_cart))
            {
                return;
            }

            // When transferring gold to player simply add to player's gold count
            if (item.IsOfTemplate(ItemGroups.Currency, (int)Currency.Gold_pieces) && PlayerEntity.Items == to)
            {
                playerEntity.GoldPieces += item.stackCount;
                from.RemoveItem(item);
                Refresh(false);
                return;
            }

            to.Transfer(item, from, preferredOrder);
            Refresh(false);
        }
        public override void OnPush()
        {
            // Local items always points to player inventory
            localItems = PlayerEntity.Items;

            // Start a new dropped items target
            droppedItems.Clear();
            remoteItems = droppedItems;
            remoteTargetType = RemoteTargetTypes.Dropped;

            // Use custom loot target if specified
            if (lootTarget != null)
            {
                remoteItems = lootTarget.Items;
                remoteTargetType = RemoteTargetTypes.Loot;
                lootTarget.OnInventoryOpen();
            }

            // Clear wagon button state on open
            if (wagonButton != null)
            {
                usingWagon = false;
                wagonButton.BackgroundTexture = wagonNotSelected;
            }

            // Set default button by context
            if (removeButton != null && lootTarget != null)
            {
                // When looting, make "remove" default action so player does not accidentially equip when picking up
                SelectActionMode(ActionModes.Remove);
            }
            else if (equipButton != null && lootTarget == null)
            {
                // When managing inventory only, make "equip" default action so player can manage gear
                SelectActionMode(ActionModes.Equip);
            }

            // Reset scrollbars
            if (localItemsScrollBar != null)
                localItemsScrollBar.ScrollIndex = 0;
            if (remoteItemsScrollBar != null)
                remoteItemsScrollBar.ScrollIndex = 0;

            // Refresh window
            Refresh();
        }
        /// <summary>
        /// Deserialize equip table and attempt to relink equipped items in collection.
        /// Item UID must exist inside collection provided or entry will not be restored and item not equipped.
        /// </summary>
        /// <param name="data">UID array exactly this.equipTableLength in length.</param>
        /// <param name="items">Item collection.</param>
        public void DeserializeEquipTable(ulong[] data, ItemCollection items)
        {
            if (data == null || items == null || data.Length != equipTableLength)
                return;

            Clear();

            for (int i = 0; i < equipTableLength; i++)
            {
                ulong uid = data[i];
                if (items.Contains(uid))
                {
                    DaggerfallUnityItem item = items.GetItem(uid);
                    if (item != null)
                    {
                        equipTable[i] = item;
                        item.EquipSlot = (EquipSlots)i;
                    }
                }
            }
        }
        void ShowWagon(bool show)
        {
            if (show)
            {
                // Save current target and switch to wagon
                wagonButton.BackgroundTexture = wagonSelected;
                lastRemoteItems = remoteItems;
                lastRemoteTargetType = remoteTargetType;
                remoteItems = PlayerEntity.WagonItems;
                remoteTargetType = RemoteTargetTypes.Wagon;
            }
            else
            {
                // Restore previous target or default to dropped items
                wagonButton.BackgroundTexture = wagonNotSelected;
                if (lastRemoteItems != null)
                {
                    remoteItems = lastRemoteItems;
                    remoteTargetType = lastRemoteTargetType;
                    lastRemoteItems = null;
                }
                else
                {
                    remoteItems = droppedItems;
                    remoteTargetType = RemoteTargetTypes.Dropped;
                    lastRemoteItems = null;
                }
            }

            usingWagon = show;
            Refresh(false);
        }
        /// <summary>
        /// Transfers all items from another collection.
        /// Items will be removed from source collection and placed in this collection.
        /// UIDs will be retained.
        /// </summary>
        /// <param name="source">Source collection to transfer from.</param>
        public void TransferAll(ItemCollection source)
        {
            if (source == null)
                return;

            foreach (DaggerfallUnityItem item in source.items.Values)
            {
                AddItem(item);
            }

            source.Clear();
        }
        /// <summary>
        /// Transfers a single item from another collection to this collection.
        /// Item will be removed from source collection and placed in this collection.
        /// UID will be retained.
        /// </summary>
        /// <param name="item">Item to transfer.</param>
        /// <param name="source">Source collection to transfer from.</param>
        /// <param name="position">Position in list to transfer item.</param>
        public void Transfer(DaggerfallUnityItem item, ItemCollection source, AddPosition position = AddPosition.DontCare)
        {
            if (item == null || source == null)
                return;

            source.RemoveItem(item);
            AddItem(item, position);
        }
        /// <summary>
        /// Replaces all items in this collection with clones of items from source collection.
        /// Items in this collection will be destroyed. Source items will not be changed.
        /// New UIDs will be allocated to cloned items.
        /// </summary>
        /// <param name="source">Source collection to copy from.</param>
        public void ReplaceAll(ItemCollection source)
        {
            if (source == null)
                return;

            Clear();
            CopyAll(source);
        }
        /// <summary>
        /// Clones all items from source collection into this collection.
        /// Source items will not be changed.
        /// New UIDs will be allocated to cloned items.
        /// </summary>
        /// <param name="source">Source collection to copy from.</param>
        public void CopyAll(ItemCollection source)
        {
            if (source == null)
                return;

            foreach (DaggerfallUnityItem item in source.items.Values)
            {
                AddItem(item.Clone());
            }
        }
        /// <summary>
        /// Assigns basic starting gear to a new character.
        /// </summary>
        public void AssignStartingGear(PlayerEntity playerEntity)
        {
            // Get references
            ItemCollection items      = playerEntity.Items;
            ItemEquipTable equipTable = playerEntity.ItemEquipTable;

            // Starting clothes are gender-specific
            DaggerfallUnityItem shortShirt  = null;
            DaggerfallUnityItem casualPants = null;

            if (playerEntity.Gender == Genders.Female)
            {
                shortShirt  = ItemBuilder.CreateWomensClothing(WomensClothing.Short_shirt_closed, playerEntity.Race, 0);
                casualPants = ItemBuilder.CreateWomensClothing(WomensClothing.Casual_pants, playerEntity.Race);
            }
            else
            {
                shortShirt  = ItemBuilder.CreateMensClothing(MensClothing.Short_shirt, playerEntity.Race, 0);
                casualPants = ItemBuilder.CreateMensClothing(MensClothing.Casual_pants, playerEntity.Race);
            }

            // Randomise shirt dye and pants variant
            shortShirt.dyeColor = ItemBuilder.RandomClothingDye();
            ItemBuilder.RandomizeClothingVariant(casualPants);

            // Add a horse
            // This helps player get around
            // Free horse will be removed once shops are implemented
            items.AddItem(ItemBuilder.CreateItem(ItemGroups.Transportation, (int)Transportation.Horse));

            // Add a wagon
            // This is required for now as shops not currently implemented
            // Wagon is easy to obtain anyway (150g) and most player can affored right out of Privateer's Hold
            // TODO: Remove this once shops can sell this item to players as normal
            items.AddItem(ItemBuilder.CreateItem(ItemGroups.Transportation, (int)Transportation.Small_cart));

            // Add spellbook, all players start with one
            items.AddItem(ItemBuilder.CreateItem(ItemGroups.MiscItems, (int)MiscItems.Spellbook));

            // Add and equip clothing
            items.AddItem(shortShirt);
            items.AddItem(casualPants);
            equipTable.EquipItem(shortShirt, true, false);
            equipTable.EquipItem(casualPants, true, false);

            // Always add ebony dagger until biography implemented
            items.AddItem(ItemBuilder.CreateWeapon(Weapons.Dagger, WeaponMaterialTypes.Ebony));

            // Add a cuirass
            items.AddItem(ItemBuilder.CreateArmor(playerEntity.Gender, playerEntity.Race, Armor.Cuirass, ArmorMaterialTypes.Leather));

            // Add alternate weapons
            items.AddItem(ItemBuilder.CreateWeapon(Weapons.Longsword, WeaponMaterialTypes.Steel));
            items.AddItem(ItemBuilder.CreateWeapon(Weapons.Katana, WeaponMaterialTypes.Iron));
            items.AddItem(ItemBuilder.CreateWeapon(Weapons.Staff, WeaponMaterialTypes.Silver));
            items.AddItem(ItemBuilder.CreateWeapon(Weapons.Long_Bow, WeaponMaterialTypes.Silver));

            // Add some ingredients
            for (int i = 0; i < 10; i++)
            {
                items.AddItem(ItemBuilder.CreateRandomIngredient());
                items.AddItem(ItemBuilder.CreateRandomBook());
            }

            // Add some starting gold
            playerEntity.GoldPieces += 100;
        }